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);
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_renameat(vfs_handle_struct *handle,
563 files_struct *srcfsp,
564 const struct smb_filename *smb_fname_src,
565 files_struct *dstfsp,
566 const struct smb_filename *smb_fname_dst)
568 TALLOC_CTX *ctx = talloc_tos();
569 struct smb_filename *smb_fname_src_tmp = NULL;
570 struct smb_filename *smb_fname_dst_tmp = NULL;
571 char *src_name_mapped = NULL;
572 char *dst_name_mapped = NULL;
576 status = catia_string_replace_allocate(handle->conn,
577 smb_fname_src->base_name,
578 &src_name_mapped, vfs_translate_to_unix);
579 if (!NT_STATUS_IS_OK(status)) {
580 errno = map_errno_from_nt_status(status);
584 status = catia_string_replace_allocate(handle->conn,
585 smb_fname_dst->base_name,
586 &dst_name_mapped, vfs_translate_to_unix);
587 if (!NT_STATUS_IS_OK(status)) {
588 errno = map_errno_from_nt_status(status);
592 /* Setup temporary smb_filename structs. */
593 smb_fname_src_tmp = cp_smb_filename(ctx, smb_fname_src);
594 if (smb_fname_src_tmp == NULL) {
599 smb_fname_dst_tmp = cp_smb_filename(ctx, smb_fname_dst);
600 if (smb_fname_dst_tmp == NULL) {
605 smb_fname_src_tmp->base_name = src_name_mapped;
606 smb_fname_dst_tmp->base_name = dst_name_mapped;
607 DEBUG(10, ("converted old name: %s\n",
608 smb_fname_str_dbg(smb_fname_src_tmp)));
609 DEBUG(10, ("converted new name: %s\n",
610 smb_fname_str_dbg(smb_fname_dst_tmp)));
612 ret = SMB_VFS_NEXT_RENAMEAT(handle,
619 TALLOC_FREE(src_name_mapped);
620 TALLOC_FREE(dst_name_mapped);
621 TALLOC_FREE(smb_fname_src_tmp);
622 TALLOC_FREE(smb_fname_dst_tmp);
627 static int catia_stat(vfs_handle_struct *handle,
628 struct smb_filename *smb_fname)
635 status = catia_string_replace_allocate(handle->conn,
636 smb_fname->base_name,
637 &name, vfs_translate_to_unix);
638 if (!NT_STATUS_IS_OK(status)) {
639 errno = map_errno_from_nt_status(status);
643 tmp_base_name = smb_fname->base_name;
644 smb_fname->base_name = name;
646 ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
647 smb_fname->base_name = tmp_base_name;
653 static int catia_lstat(vfs_handle_struct *handle,
654 struct smb_filename *smb_fname)
661 status = catia_string_replace_allocate(handle->conn,
662 smb_fname->base_name,
663 &name, vfs_translate_to_unix);
664 if (!NT_STATUS_IS_OK(status)) {
665 errno = map_errno_from_nt_status(status);
669 tmp_base_name = smb_fname->base_name;
670 smb_fname->base_name = name;
672 ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
673 smb_fname->base_name = tmp_base_name;
679 static int catia_unlinkat(vfs_handle_struct *handle,
680 struct files_struct *dirfsp,
681 const struct smb_filename *smb_fname,
684 struct smb_filename *smb_fname_tmp = NULL;
689 status = catia_string_replace_allocate(handle->conn,
690 smb_fname->base_name,
691 &name, vfs_translate_to_unix);
692 if (!NT_STATUS_IS_OK(status)) {
693 errno = map_errno_from_nt_status(status);
697 /* Setup temporary smb_filename structs. */
698 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
699 if (smb_fname_tmp == NULL) {
704 smb_fname_tmp->base_name = name;
705 ret = SMB_VFS_NEXT_UNLINKAT(handle,
709 TALLOC_FREE(smb_fname_tmp);
715 static int catia_lchown(vfs_handle_struct *handle,
716 const struct smb_filename *smb_fname,
724 struct smb_filename *catia_smb_fname = NULL;
726 status = catia_string_replace_allocate(handle->conn,
727 smb_fname->base_name,
729 vfs_translate_to_unix);
730 if (!NT_STATUS_IS_OK(status)) {
731 errno = map_errno_from_nt_status(status);
734 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
739 if (catia_smb_fname == NULL) {
745 ret = SMB_VFS_NEXT_LCHOWN(handle, catia_smb_fname, uid, gid);
748 TALLOC_FREE(catia_smb_fname);
753 static int catia_chmod(vfs_handle_struct *handle,
754 const struct smb_filename *smb_fname,
761 struct smb_filename *catia_smb_fname = NULL;
763 status = catia_string_replace_allocate(handle->conn,
764 smb_fname->base_name,
766 vfs_translate_to_unix);
767 if (!NT_STATUS_IS_OK(status)) {
768 errno = map_errno_from_nt_status(status);
771 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
776 if (catia_smb_fname == NULL) {
782 ret = SMB_VFS_NEXT_CHMOD(handle, catia_smb_fname, mode);
785 TALLOC_FREE(catia_smb_fname);
790 static int catia_mkdirat(vfs_handle_struct *handle,
791 struct files_struct *dirfsp,
792 const struct smb_filename *smb_fname,
798 struct smb_filename *catia_smb_fname = NULL;
800 status = catia_string_replace_allocate(handle->conn,
801 smb_fname->base_name,
803 vfs_translate_to_unix);
804 if (!NT_STATUS_IS_OK(status)) {
805 errno = map_errno_from_nt_status(status);
808 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
813 if (catia_smb_fname == NULL) {
819 ret = SMB_VFS_NEXT_MKDIRAT(handle,
824 TALLOC_FREE(catia_smb_fname);
829 static int catia_chdir(vfs_handle_struct *handle,
830 const struct smb_filename *smb_fname)
833 struct smb_filename *catia_smb_fname = NULL;
837 status = catia_string_replace_allocate(handle->conn,
838 smb_fname->base_name,
840 vfs_translate_to_unix);
841 if (!NT_STATUS_IS_OK(status)) {
842 errno = map_errno_from_nt_status(status);
846 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
851 if (catia_smb_fname == NULL) {
856 ret = SMB_VFS_NEXT_CHDIR(handle, catia_smb_fname);
858 TALLOC_FREE(catia_smb_fname);
863 static int catia_ntimes(vfs_handle_struct *handle,
864 const struct smb_filename *smb_fname,
865 struct smb_file_time *ft)
867 struct smb_filename *smb_fname_tmp = NULL;
872 status = catia_string_replace_allocate(handle->conn,
873 smb_fname->base_name,
874 &name, vfs_translate_to_unix);
875 if (!NT_STATUS_IS_OK(status)) {
876 errno = map_errno_from_nt_status(status);
880 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
881 if (smb_fname_tmp == NULL) {
886 smb_fname_tmp->base_name = name;
887 ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
889 TALLOC_FREE(smb_fname_tmp);
894 static struct smb_filename *
895 catia_realpath(vfs_handle_struct *handle,
897 const struct smb_filename *smb_fname)
899 char *mapped_name = NULL;
900 struct smb_filename *catia_smb_fname = NULL;
901 struct smb_filename *return_fname = NULL;
904 status = catia_string_replace_allocate(handle->conn,
905 smb_fname->base_name,
906 &mapped_name, vfs_translate_to_unix);
907 if (!NT_STATUS_IS_OK(status)) {
908 errno = map_errno_from_nt_status(status);
912 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
917 if (catia_smb_fname == NULL) {
918 TALLOC_FREE(mapped_name);
922 return_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, catia_smb_fname);
923 TALLOC_FREE(mapped_name);
924 TALLOC_FREE(catia_smb_fname);
928 static int catia_chflags(struct vfs_handle_struct *handle,
929 const struct smb_filename *smb_fname,
933 struct smb_filename *catia_smb_fname = NULL;
937 status = catia_string_replace_allocate(handle->conn,
938 smb_fname->base_name,
940 vfs_translate_to_unix);
941 if (!NT_STATUS_IS_OK(status)) {
942 errno = map_errno_from_nt_status(status);
945 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
950 if (catia_smb_fname == NULL) {
956 ret = SMB_VFS_NEXT_CHFLAGS(handle, catia_smb_fname, flags);
958 TALLOC_FREE(catia_smb_fname);
964 catia_streaminfo(struct vfs_handle_struct *handle,
965 struct files_struct *fsp,
966 const struct smb_filename *smb_fname,
968 unsigned int *_num_streams,
969 struct stream_struct **_streams)
971 char *mapped_name = NULL;
974 struct smb_filename *catia_smb_fname = NULL;
975 unsigned int num_streams = 0;
976 struct stream_struct *streams = NULL;
981 status = catia_string_replace_allocate(handle->conn,
982 smb_fname->base_name,
984 vfs_translate_to_unix);
985 if (!NT_STATUS_IS_OK(status)) {
986 errno = map_errno_from_nt_status(status);
990 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
995 if (catia_smb_fname == NULL) {
996 TALLOC_FREE(mapped_name);
997 return NT_STATUS_NO_MEMORY;
1000 status = SMB_VFS_NEXT_STREAMINFO(handle, fsp, catia_smb_fname,
1001 mem_ctx, &num_streams, &streams);
1002 TALLOC_FREE(mapped_name);
1003 TALLOC_FREE(catia_smb_fname);
1004 if (!NT_STATUS_IS_OK(status)) {
1009 * Translate stream names just like the base names
1011 for (i = 0; i < num_streams; i++) {
1013 * Strip ":" prefix and ":$DATA" suffix to get a
1014 * "pure" stream name and only translate that.
1016 void *old_ptr = streams[i].name;
1017 char *stream_name = streams[i].name + 1;
1018 char *stream_type = strrchr_m(stream_name, ':');
1020 if (stream_type != NULL) {
1021 *stream_type = '\0';
1025 status = catia_string_replace_allocate(handle->conn, stream_name,
1026 &mapped_name, vfs_translate_to_windows);
1027 if (!NT_STATUS_IS_OK(status)) {
1028 TALLOC_FREE(streams);
1032 if (stream_type != NULL) {
1033 streams[i].name = talloc_asprintf(streams, ":%s:%s",
1034 mapped_name, stream_type);
1036 streams[i].name = talloc_asprintf(streams, ":%s",
1039 TALLOC_FREE(mapped_name);
1040 TALLOC_FREE(old_ptr);
1041 if (streams[i].name == NULL) {
1042 TALLOC_FREE(streams);
1043 return NT_STATUS_NO_MEMORY;
1047 *_num_streams = num_streams;
1048 *_streams = streams;
1049 return NT_STATUS_OK;
1053 catia_get_nt_acl(struct vfs_handle_struct *handle,
1054 const struct smb_filename *smb_fname,
1055 uint32_t security_info,
1056 TALLOC_CTX *mem_ctx,
1057 struct security_descriptor **ppdesc)
1059 char *mapped_name = NULL;
1060 const char *path = smb_fname->base_name;
1061 struct smb_filename *mapped_smb_fname = NULL;
1064 status = catia_string_replace_allocate(handle->conn,
1065 path, &mapped_name, vfs_translate_to_unix);
1066 if (!NT_STATUS_IS_OK(status)) {
1067 errno = map_errno_from_nt_status(status);
1070 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1075 if (mapped_smb_fname == NULL) {
1076 TALLOC_FREE(mapped_name);
1077 return NT_STATUS_NO_MEMORY;
1080 status = SMB_VFS_NEXT_GET_NT_ACL(handle, mapped_smb_fname,
1081 security_info, mem_ctx, ppdesc);
1082 TALLOC_FREE(mapped_name);
1083 TALLOC_FREE(mapped_smb_fname);
1089 catia_sys_acl_get_file(vfs_handle_struct *handle,
1090 const struct smb_filename *smb_fname,
1091 SMB_ACL_TYPE_T type,
1092 TALLOC_CTX *mem_ctx)
1094 char *mapped_name = NULL;
1095 struct smb_filename *mapped_smb_fname = NULL;
1098 int saved_errno = 0;
1100 status = catia_string_replace_allocate(handle->conn,
1101 smb_fname->base_name,
1103 vfs_translate_to_unix);
1104 if (!NT_STATUS_IS_OK(status)) {
1105 errno = map_errno_from_nt_status(status);
1106 return (SMB_ACL_T)NULL;
1109 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1114 if (mapped_smb_fname == NULL) {
1115 TALLOC_FREE(mapped_name);
1117 return (SMB_ACL_T)NULL;
1120 ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, mapped_smb_fname,
1122 if (ret == (SMB_ACL_T)NULL) {
1123 saved_errno = errno;
1125 TALLOC_FREE(mapped_smb_fname);
1126 TALLOC_FREE(mapped_name);
1127 if (saved_errno != 0) {
1128 errno = saved_errno;
1134 catia_sys_acl_set_file(vfs_handle_struct *handle,
1135 const struct smb_filename *smb_fname,
1136 SMB_ACL_TYPE_T type,
1139 struct smb_filename *mapped_smb_fname = NULL;
1140 int saved_errno = 0;
1141 char *mapped_name = NULL;
1145 status = catia_string_replace_allocate(handle->conn,
1146 smb_fname->base_name,
1148 vfs_translate_to_unix);
1149 if (!NT_STATUS_IS_OK(status)) {
1150 errno = map_errno_from_nt_status(status);
1154 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1159 if (mapped_smb_fname == NULL) {
1160 TALLOC_FREE(mapped_name);
1165 ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, mapped_smb_fname,
1168 saved_errno = errno;
1170 TALLOC_FREE(mapped_smb_fname);
1171 TALLOC_FREE(mapped_name);
1172 if (saved_errno != 0) {
1173 errno = saved_errno;
1179 catia_sys_acl_delete_def_file(vfs_handle_struct *handle,
1180 const struct smb_filename *smb_fname)
1182 struct smb_filename *mapped_smb_fname = NULL;
1183 int saved_errno = 0;
1184 char *mapped_name = NULL;
1188 status = catia_string_replace_allocate(handle->conn,
1189 smb_fname->base_name,
1191 vfs_translate_to_unix);
1192 if (!NT_STATUS_IS_OK(status)) {
1193 errno = map_errno_from_nt_status(status);
1197 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1202 if (mapped_smb_fname == NULL) {
1203 TALLOC_FREE(mapped_name);
1207 ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, mapped_smb_fname);
1209 saved_errno = errno;
1211 TALLOC_FREE(mapped_smb_fname);
1212 TALLOC_FREE(mapped_name);
1213 if (saved_errno != 0) {
1214 errno = saved_errno;
1220 catia_getxattr(vfs_handle_struct *handle,
1221 const struct smb_filename *smb_fname,
1226 struct smb_filename *mapped_smb_fname = NULL;
1227 char *mapped_name = NULL;
1228 char *mapped_ea_name = NULL;
1231 int saved_errno = 0;
1233 status = catia_string_replace_allocate(handle->conn,
1234 smb_fname->base_name,
1236 vfs_translate_to_unix);
1237 if (!NT_STATUS_IS_OK(status)) {
1238 errno = map_errno_from_nt_status(status);
1242 status = catia_string_replace_allocate(handle->conn,
1243 name, &mapped_ea_name, vfs_translate_to_unix);
1244 if (!NT_STATUS_IS_OK(status)) {
1245 TALLOC_FREE(mapped_name);
1246 errno = map_errno_from_nt_status(status);
1250 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1255 if (mapped_smb_fname == NULL) {
1256 TALLOC_FREE(mapped_name);
1257 TALLOC_FREE(mapped_ea_name);
1262 ret = SMB_VFS_NEXT_GETXATTR(handle, mapped_smb_fname,
1263 mapped_ea_name, value, size);
1265 saved_errno = errno;
1267 TALLOC_FREE(mapped_name);
1268 TALLOC_FREE(mapped_ea_name);
1269 TALLOC_FREE(mapped_smb_fname);
1270 if (saved_errno != 0) {
1271 errno = saved_errno;
1278 catia_listxattr(vfs_handle_struct *handle,
1279 const struct smb_filename *smb_fname,
1280 char *list, size_t size)
1282 struct smb_filename *mapped_smb_fname = NULL;
1283 char *mapped_name = NULL;
1286 int saved_errno = 0;
1288 status = catia_string_replace_allocate(handle->conn,
1289 smb_fname->base_name,
1291 vfs_translate_to_unix);
1292 if (!NT_STATUS_IS_OK(status)) {
1293 errno = map_errno_from_nt_status(status);
1297 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1302 if (mapped_smb_fname == NULL) {
1303 TALLOC_FREE(mapped_name);
1308 ret = SMB_VFS_NEXT_LISTXATTR(handle, mapped_smb_fname, list, size);
1310 saved_errno = errno;
1312 TALLOC_FREE(mapped_name);
1313 TALLOC_FREE(mapped_smb_fname);
1314 if (saved_errno != 0) {
1315 errno = saved_errno;
1322 catia_removexattr(vfs_handle_struct *handle,
1323 const struct smb_filename *smb_fname,
1326 struct smb_filename *mapped_smb_fname = NULL;
1327 char *mapped_name = NULL;
1328 char *mapped_ea_name = NULL;
1331 int saved_errno = 0;
1333 status = catia_string_replace_allocate(handle->conn,
1334 smb_fname->base_name,
1336 vfs_translate_to_unix);
1337 if (!NT_STATUS_IS_OK(status)) {
1338 errno = map_errno_from_nt_status(status);
1342 status = catia_string_replace_allocate(handle->conn,
1343 name, &mapped_ea_name, vfs_translate_to_unix);
1344 if (!NT_STATUS_IS_OK(status)) {
1345 TALLOC_FREE(mapped_name);
1346 errno = map_errno_from_nt_status(status);
1350 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1355 if (mapped_smb_fname == NULL) {
1356 TALLOC_FREE(mapped_name);
1357 TALLOC_FREE(mapped_ea_name);
1362 ret = SMB_VFS_NEXT_REMOVEXATTR(handle, mapped_smb_fname,
1365 saved_errno = errno;
1367 TALLOC_FREE(mapped_name);
1368 TALLOC_FREE(mapped_ea_name);
1369 TALLOC_FREE(mapped_smb_fname);
1370 if (saved_errno != 0) {
1371 errno = saved_errno;
1378 catia_setxattr(vfs_handle_struct *handle,
1379 const struct smb_filename *smb_fname,
1385 struct smb_filename *mapped_smb_fname = NULL;
1386 char *mapped_name = NULL;
1387 char *mapped_ea_name = NULL;
1390 int saved_errno = 0;
1392 status = catia_string_replace_allocate(handle->conn,
1393 smb_fname->base_name,
1395 vfs_translate_to_unix);
1396 if (!NT_STATUS_IS_OK(status)) {
1397 errno = map_errno_from_nt_status(status);
1401 status = catia_string_replace_allocate(handle->conn,
1402 name, &mapped_ea_name, vfs_translate_to_unix);
1403 if (!NT_STATUS_IS_OK(status)) {
1404 TALLOC_FREE(mapped_name);
1405 errno = map_errno_from_nt_status(status);
1409 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1414 if (mapped_smb_fname == NULL) {
1415 TALLOC_FREE(mapped_name);
1416 TALLOC_FREE(mapped_ea_name);
1421 ret = SMB_VFS_NEXT_SETXATTR(handle, mapped_smb_fname, mapped_ea_name,
1422 value, size, flags);
1424 saved_errno = errno;
1426 TALLOC_FREE(mapped_name);
1427 TALLOC_FREE(mapped_ea_name);
1428 TALLOC_FREE(mapped_smb_fname);
1429 if (saved_errno != 0) {
1430 errno = saved_errno;
1436 static int catia_fstat(vfs_handle_struct *handle,
1438 SMB_STRUCT_STAT *sbuf)
1440 struct catia_cache *cc = NULL;
1443 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1448 ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
1450 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1455 static ssize_t catia_pread(vfs_handle_struct *handle,
1456 files_struct *fsp, void *data,
1457 size_t n, off_t offset)
1459 struct catia_cache *cc = NULL;
1463 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1468 result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
1470 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1475 static ssize_t catia_pwrite(vfs_handle_struct *handle,
1476 files_struct *fsp, const void *data,
1477 size_t n, off_t offset)
1479 struct catia_cache *cc = NULL;
1483 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1488 result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
1490 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1495 static int catia_ftruncate(struct vfs_handle_struct *handle,
1496 struct files_struct *fsp,
1499 struct catia_cache *cc = NULL;
1502 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1507 ret = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
1509 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1514 static int catia_fallocate(struct vfs_handle_struct *handle,
1515 struct files_struct *fsp,
1520 struct catia_cache *cc = NULL;
1523 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1528 ret = SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
1530 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1535 static ssize_t catia_fgetxattr(struct vfs_handle_struct *handle,
1536 struct files_struct *fsp,
1541 char *mapped_xattr_name = NULL;
1545 status = catia_string_replace_allocate(handle->conn,
1546 name, &mapped_xattr_name,
1547 vfs_translate_to_unix);
1548 if (!NT_STATUS_IS_OK(status)) {
1549 errno = map_errno_from_nt_status(status);
1553 result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, mapped_xattr_name,
1556 TALLOC_FREE(mapped_xattr_name);
1561 static ssize_t catia_flistxattr(struct vfs_handle_struct *handle,
1562 struct files_struct *fsp,
1566 struct catia_cache *cc = NULL;
1570 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1575 result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
1577 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1582 static int catia_fremovexattr(struct vfs_handle_struct *handle,
1583 struct files_struct *fsp,
1586 char *mapped_name = NULL;
1590 status = catia_string_replace_allocate(handle->conn,
1591 name, &mapped_name, vfs_translate_to_unix);
1592 if (!NT_STATUS_IS_OK(status)) {
1593 errno = map_errno_from_nt_status(status);
1597 ret = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, mapped_name);
1599 TALLOC_FREE(mapped_name);
1604 static int catia_fsetxattr(struct vfs_handle_struct *handle,
1605 struct files_struct *fsp,
1611 char *mapped_xattr_name = NULL;
1615 status = catia_string_replace_allocate(
1616 handle->conn, name, &mapped_xattr_name, vfs_translate_to_unix);
1617 if (!NT_STATUS_IS_OK(status)) {
1618 errno = map_errno_from_nt_status(status);
1622 ret = SMB_VFS_NEXT_FSETXATTR(handle, fsp, mapped_xattr_name,
1623 value, size, flags);
1625 TALLOC_FREE(mapped_xattr_name);
1630 static SMB_ACL_T catia_sys_acl_get_fd(vfs_handle_struct *handle,
1632 TALLOC_CTX *mem_ctx)
1634 struct catia_cache *cc = NULL;
1635 struct smb_acl_t *result = NULL;
1638 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1643 result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx);
1645 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1650 static int catia_sys_acl_blob_get_fd(vfs_handle_struct *handle,
1652 TALLOC_CTX *mem_ctx,
1653 char **blob_description,
1656 struct catia_cache *cc = NULL;
1659 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1664 ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx,
1665 blob_description, blob);
1667 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1672 static int catia_sys_acl_set_fd(vfs_handle_struct *handle,
1676 struct catia_cache *cc = NULL;
1679 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1684 ret = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl);
1686 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1691 static NTSTATUS catia_fget_nt_acl(vfs_handle_struct *handle,
1693 uint32_t security_info,
1694 TALLOC_CTX *mem_ctx,
1695 struct security_descriptor **ppdesc)
1697 struct catia_cache *cc = NULL;
1701 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1703 return map_nt_error_from_unix(errno);
1706 status = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info,
1709 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1714 static NTSTATUS catia_fset_nt_acl(vfs_handle_struct *handle,
1716 uint32_t security_info_sent,
1717 const struct security_descriptor *psd)
1719 struct catia_cache *cc = NULL;
1723 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1725 return map_nt_error_from_unix(errno);
1728 status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
1730 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1735 static NTSTATUS catia_fset_dos_attributes(struct vfs_handle_struct *handle,
1736 struct files_struct *fsp,
1739 struct catia_cache *cc = NULL;
1743 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1745 return map_nt_error_from_unix(errno);
1748 status = SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, dosmode);
1750 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1755 static NTSTATUS catia_fget_dos_attributes(struct vfs_handle_struct *handle,
1756 struct files_struct *fsp,
1759 struct catia_cache *cc = NULL;
1763 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1765 return map_nt_error_from_unix(errno);
1768 status = SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
1770 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1775 static int catia_fchown(vfs_handle_struct *handle,
1780 struct catia_cache *cc = NULL;
1783 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1788 ret = SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid);
1790 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1795 static int catia_fchmod(vfs_handle_struct *handle,
1799 struct catia_cache *cc = NULL;
1802 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1807 ret = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
1809 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1814 struct catia_pread_state {
1816 struct vfs_aio_state vfs_aio_state;
1817 struct files_struct *fsp;
1818 struct catia_cache *cc;
1821 static void catia_pread_done(struct tevent_req *subreq);
1823 static struct tevent_req *catia_pread_send(struct vfs_handle_struct *handle,
1824 TALLOC_CTX *mem_ctx,
1825 struct tevent_context *ev,
1826 struct files_struct *fsp,
1831 struct tevent_req *req = NULL, *subreq = NULL;
1832 struct catia_pread_state *state = NULL;
1835 req = tevent_req_create(mem_ctx, &state,
1836 struct catia_pread_state);
1842 ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
1844 tevent_req_error(req, errno);
1845 return tevent_req_post(req, ev);
1848 subreq = SMB_VFS_NEXT_PREAD_SEND(state, ev, handle, fsp, data,
1850 if (tevent_req_nomem(subreq, req)) {
1851 return tevent_req_post(req, ev);
1853 tevent_req_set_callback(subreq, catia_pread_done, req);
1858 static void catia_pread_done(struct tevent_req *subreq)
1860 struct tevent_req *req = tevent_req_callback_data(
1861 subreq, struct tevent_req);
1862 struct catia_pread_state *state = tevent_req_data(
1863 req, struct catia_pread_state);
1865 state->ret = SMB_VFS_PREAD_RECV(subreq, &state->vfs_aio_state);
1866 TALLOC_FREE(subreq);
1868 CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
1870 tevent_req_done(req);
1873 static ssize_t catia_pread_recv(struct tevent_req *req,
1874 struct vfs_aio_state *vfs_aio_state)
1876 struct catia_pread_state *state = tevent_req_data(
1877 req, struct catia_pread_state);
1879 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1883 *vfs_aio_state = state->vfs_aio_state;
1887 struct catia_pwrite_state {
1889 struct vfs_aio_state vfs_aio_state;
1890 struct files_struct *fsp;
1891 struct catia_cache *cc;
1894 static void catia_pwrite_done(struct tevent_req *subreq);
1896 static struct tevent_req *catia_pwrite_send(struct vfs_handle_struct *handle,
1897 TALLOC_CTX *mem_ctx,
1898 struct tevent_context *ev,
1899 struct files_struct *fsp,
1904 struct tevent_req *req = NULL, *subreq = NULL;
1905 struct catia_pwrite_state *state = NULL;
1908 req = tevent_req_create(mem_ctx, &state,
1909 struct catia_pwrite_state);
1915 ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
1917 tevent_req_error(req, errno);
1918 return tevent_req_post(req, ev);
1921 subreq = SMB_VFS_NEXT_PWRITE_SEND(state, ev, handle, fsp, data,
1923 if (tevent_req_nomem(subreq, req)) {
1924 return tevent_req_post(req, ev);
1926 tevent_req_set_callback(subreq, catia_pwrite_done, req);
1931 static void catia_pwrite_done(struct tevent_req *subreq)
1933 struct tevent_req *req = tevent_req_callback_data(
1934 subreq, struct tevent_req);
1935 struct catia_pwrite_state *state = tevent_req_data(
1936 req, struct catia_pwrite_state);
1938 state->ret = SMB_VFS_PWRITE_RECV(subreq, &state->vfs_aio_state);
1939 TALLOC_FREE(subreq);
1941 CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
1943 tevent_req_done(req);
1946 static ssize_t catia_pwrite_recv(struct tevent_req *req,
1947 struct vfs_aio_state *vfs_aio_state)
1949 struct catia_pwrite_state *state = tevent_req_data(
1950 req, struct catia_pwrite_state);
1952 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1956 *vfs_aio_state = state->vfs_aio_state;
1960 static off_t catia_lseek(vfs_handle_struct *handle,
1965 struct catia_cache *cc = NULL;
1969 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1974 result = SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence);
1976 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1981 struct catia_fsync_state {
1983 struct vfs_aio_state vfs_aio_state;
1984 struct files_struct *fsp;
1985 struct catia_cache *cc;
1988 static void catia_fsync_done(struct tevent_req *subreq);
1990 static struct tevent_req *catia_fsync_send(struct vfs_handle_struct *handle,
1991 TALLOC_CTX *mem_ctx,
1992 struct tevent_context *ev,
1993 struct files_struct *fsp)
1995 struct tevent_req *req = NULL, *subreq = NULL;
1996 struct catia_fsync_state *state = NULL;
1999 req = tevent_req_create(mem_ctx, &state,
2000 struct catia_fsync_state);
2006 ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
2008 tevent_req_error(req, errno);
2009 return tevent_req_post(req, ev);
2012 subreq = SMB_VFS_NEXT_FSYNC_SEND(state, ev, handle, fsp);
2013 if (tevent_req_nomem(subreq, req)) {
2014 return tevent_req_post(req, ev);
2016 tevent_req_set_callback(subreq, catia_fsync_done, req);
2021 static void catia_fsync_done(struct tevent_req *subreq)
2023 struct tevent_req *req = tevent_req_callback_data(
2024 subreq, struct tevent_req);
2025 struct catia_fsync_state *state = tevent_req_data(
2026 req, struct catia_fsync_state);
2028 state->ret = SMB_VFS_FSYNC_RECV(subreq, &state->vfs_aio_state);
2029 TALLOC_FREE(subreq);
2031 CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
2033 tevent_req_done(req);
2036 static int catia_fsync_recv(struct tevent_req *req,
2037 struct vfs_aio_state *vfs_aio_state)
2039 struct catia_fsync_state *state = tevent_req_data(
2040 req, struct catia_fsync_state);
2042 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
2046 *vfs_aio_state = state->vfs_aio_state;
2050 static bool catia_lock(vfs_handle_struct *handle,
2057 struct catia_cache *cc = NULL;
2061 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2066 ok = SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type);
2068 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2073 static int catia_kernel_flock(struct vfs_handle_struct *handle,
2074 struct files_struct *fsp,
2075 uint32_t share_mode,
2076 uint32_t access_mask)
2078 struct catia_cache *cc = NULL;
2081 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2086 ret = SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, share_mode, access_mask);
2088 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2093 static int catia_linux_setlease(vfs_handle_struct *handle,
2097 struct catia_cache *cc = NULL;
2100 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2105 ret = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype);
2107 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2112 static bool catia_getlock(vfs_handle_struct *handle,
2119 struct catia_cache *cc = NULL;
2123 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2128 ok = SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid);
2130 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2135 static bool catia_strict_lock_check(struct vfs_handle_struct *handle,
2136 struct files_struct *fsp,
2137 struct lock_struct *plock)
2139 struct catia_cache *cc = NULL;
2143 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2148 ok = SMB_VFS_NEXT_STRICT_LOCK_CHECK(handle, fsp, plock);
2150 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2155 static NTSTATUS catia_fsctl(struct vfs_handle_struct *handle,
2156 struct files_struct *fsp,
2160 const uint8_t *_in_data,
2162 uint8_t **_out_data,
2163 uint32_t max_out_len,
2167 struct catia_cache *cc = NULL;
2170 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2172 return map_nt_error_from_unix(errno);
2175 result = SMB_VFS_NEXT_FSCTL(handle,
2186 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2191 static NTSTATUS catia_get_compression(vfs_handle_struct *handle,
2192 TALLOC_CTX *mem_ctx,
2193 struct files_struct *fsp,
2194 struct smb_filename *smb_fname,
2195 uint16_t *_compression_fmt)
2198 struct catia_cache *cc = NULL;
2200 struct smb_filename *mapped_smb_fname = NULL;
2201 char *mapped_name = NULL;
2204 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2206 return map_nt_error_from_unix(errno);
2208 mapped_smb_fname = fsp->fsp_name;
2210 result = catia_string_replace_allocate(handle->conn,
2211 smb_fname->base_name,
2213 vfs_translate_to_unix);
2214 if (!NT_STATUS_IS_OK(result)) {
2218 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
2223 if (mapped_smb_fname == NULL) {
2224 TALLOC_FREE(mapped_name);
2225 return NT_STATUS_NO_MEMORY;
2228 TALLOC_FREE(mapped_name);
2231 result = SMB_VFS_NEXT_GET_COMPRESSION(handle,
2238 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2240 TALLOC_FREE(mapped_smb_fname);
2246 static NTSTATUS catia_set_compression(vfs_handle_struct *handle,
2247 TALLOC_CTX *mem_ctx,
2248 struct files_struct *fsp,
2249 uint16_t compression_fmt)
2252 struct catia_cache *cc = NULL;
2255 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2257 return map_nt_error_from_unix(errno);
2260 result = SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp,
2263 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2268 static NTSTATUS catia_readdir_attr(struct vfs_handle_struct *handle,
2269 const struct smb_filename *smb_fname_in,
2270 TALLOC_CTX *mem_ctx,
2271 struct readdir_attr_data **pattr_data)
2273 struct smb_filename *smb_fname;
2277 status = catia_string_replace_allocate(handle->conn,
2278 smb_fname_in->base_name,
2280 vfs_translate_to_unix);
2281 if (!NT_STATUS_IS_OK(status)) {
2282 errno = map_errno_from_nt_status(status);
2286 smb_fname = synthetic_smb_fname(talloc_tos(), fname, NULL,
2287 &smb_fname_in->st, 0);
2289 status = SMB_VFS_NEXT_READDIR_ATTR(handle, smb_fname, mem_ctx, pattr_data);
2291 TALLOC_FREE(smb_fname);
2296 static NTSTATUS catia_get_dos_attributes(struct vfs_handle_struct *handle,
2297 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_GET_DOS_ATTRIBUTES(handle,
2324 if (NT_STATUS_IS_OK(status)) {
2325 smb_fname->st = mapped_smb_fname->st;
2328 TALLOC_FREE(mapped_name);
2329 TALLOC_FREE(mapped_smb_fname);
2334 static NTSTATUS catia_set_dos_attributes(struct vfs_handle_struct *handle,
2335 const struct smb_filename *smb_fname,
2338 char *mapped_name = NULL;
2339 const char *path = smb_fname->base_name;
2340 struct smb_filename *mapped_smb_fname = NULL;
2343 status = catia_string_replace_allocate(handle->conn,
2344 path, &mapped_name, 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_SET_DOS_ATTRIBUTES(handle,
2362 TALLOC_FREE(mapped_name);
2363 TALLOC_FREE(mapped_smb_fname);
2368 static struct vfs_fn_pointers vfs_catia_fns = {
2369 .connect_fn = catia_connect,
2371 /* Directory operations */
2372 .mkdirat_fn = catia_mkdirat,
2373 .opendir_fn = catia_opendir,
2374 .readdir_attr_fn = catia_readdir_attr,
2376 /* File operations */
2377 .open_fn = catia_open,
2378 .pread_fn = catia_pread,
2379 .pread_send_fn = catia_pread_send,
2380 .pread_recv_fn = catia_pread_recv,
2381 .pwrite_fn = catia_pwrite,
2382 .pwrite_send_fn = catia_pwrite_send,
2383 .pwrite_recv_fn = catia_pwrite_recv,
2384 .lseek_fn = catia_lseek,
2385 .renameat_fn = catia_renameat,
2386 .fsync_send_fn = catia_fsync_send,
2387 .fsync_recv_fn = catia_fsync_recv,
2388 .stat_fn = catia_stat,
2389 .fstat_fn = catia_fstat,
2390 .lstat_fn = catia_lstat,
2391 .unlinkat_fn = catia_unlinkat,
2392 .chmod_fn = catia_chmod,
2393 .fchmod_fn = catia_fchmod,
2394 .fchown_fn = catia_fchown,
2395 .lchown_fn = catia_lchown,
2396 .chdir_fn = catia_chdir,
2397 .ntimes_fn = catia_ntimes,
2398 .ftruncate_fn = catia_ftruncate,
2399 .fallocate_fn = catia_fallocate,
2400 .lock_fn = catia_lock,
2401 .kernel_flock_fn = catia_kernel_flock,
2402 .linux_setlease_fn = catia_linux_setlease,
2403 .getlock_fn = catia_getlock,
2404 .realpath_fn = catia_realpath,
2405 .chflags_fn = catia_chflags,
2406 .streaminfo_fn = catia_streaminfo,
2407 .strict_lock_check_fn = catia_strict_lock_check,
2408 .translate_name_fn = catia_translate_name,
2409 .fsctl_fn = catia_fsctl,
2410 .get_dos_attributes_fn = catia_get_dos_attributes,
2411 .get_dos_attributes_send_fn = vfs_not_implemented_get_dos_attributes_send,
2412 .get_dos_attributes_recv_fn = vfs_not_implemented_get_dos_attributes_recv,
2413 .set_dos_attributes_fn = catia_set_dos_attributes,
2414 .fset_dos_attributes_fn = catia_fset_dos_attributes,
2415 .fget_dos_attributes_fn = catia_fget_dos_attributes,
2416 .get_compression_fn = catia_get_compression,
2417 .set_compression_fn = catia_set_compression,
2419 /* NT ACL operations. */
2420 .get_nt_acl_fn = catia_get_nt_acl,
2421 .fget_nt_acl_fn = catia_fget_nt_acl,
2422 .fset_nt_acl_fn = catia_fset_nt_acl,
2424 /* POSIX ACL operations. */
2425 .sys_acl_get_file_fn = catia_sys_acl_get_file,
2426 .sys_acl_get_fd_fn = catia_sys_acl_get_fd,
2427 .sys_acl_blob_get_fd_fn = catia_sys_acl_blob_get_fd,
2428 .sys_acl_set_file_fn = catia_sys_acl_set_file,
2429 .sys_acl_set_fd_fn = catia_sys_acl_set_fd,
2430 .sys_acl_delete_def_file_fn = catia_sys_acl_delete_def_file,
2432 /* EA operations. */
2433 .getxattr_fn = catia_getxattr,
2434 .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
2435 .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
2436 .listxattr_fn = catia_listxattr,
2437 .removexattr_fn = catia_removexattr,
2438 .setxattr_fn = catia_setxattr,
2439 .fgetxattr_fn = catia_fgetxattr,
2440 .flistxattr_fn = catia_flistxattr,
2441 .fremovexattr_fn = catia_fremovexattr,
2442 .fsetxattr_fn = catia_fsetxattr,
2446 NTSTATUS vfs_catia_init(TALLOC_CTX *ctx)
2450 ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "catia",
2452 if (!NT_STATUS_IS_OK(ret))
2455 vfs_catia_debug_level = debug_add_class("catia");
2456 if (vfs_catia_debug_level == -1) {
2457 vfs_catia_debug_level = DBGC_VFS;
2458 DEBUG(0, ("vfs_catia: Couldn't register custom debugging "
2461 DEBUG(10, ("vfs_catia: Debug class number of "
2462 "'catia': %d\n", vfs_catia_debug_level));