selftest:Samba4: report when samba is started and ready
[Samba.git] / source3 / modules / vfs_catia.c
blobc362be764cc5bc41be30957b94a38a6b63e9e037
1 /*
2 * Catia VFS module
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
8 * Windows...
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/>.
30 #include "includes.h"
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;
38 #undef DBGC_CLASS
39 #define DBGC_CLASS vfs_catia_debug_level
41 struct share_mapping_entry {
42 int snum;
43 struct share_mapping_entry *next;
44 struct char_mappings **mappings;
47 struct catia_cache {
48 bool is_fsp_ext;
49 const struct catia_cache * const *busy;
50 char *orig_fname;
51 char *fname;
52 char *orig_base_fname;
53 char *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)
65 (*global) = share;
67 if (share->snum == SNUM(conn))
68 return share;
71 return share;
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));
79 if (sme == NULL)
80 return sme;
82 sme->snum = snum;
83 sme->next = srt_head;
84 srt_head = sme;
86 if (mappings == NULL) {
87 sme->mappings = NULL;
88 return sme;
91 sme->mappings = string_replace_init_map(mappings);
93 return sme;
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);
105 if (share_level) {
106 *selected_out = share_level;
107 return (share_level->mappings != NULL);
110 /* see if we have a global setting */
111 if (!global) {
112 /* 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;
123 return True;
125 if (global->mappings) {
126 share_level->mappings = global->mappings;
127 (*selected_out) = share_level;
128 return True;
131 return False;
134 static NTSTATUS catia_string_replace_allocate(connection_struct *conn,
135 const char *name_in,
136 char **mapped_name,
137 enum vfs_translate_direction direction)
139 struct share_mapping_entry *selected;
140 NTSTATUS status;
142 if (!init_mappings(conn, &selected)) {
143 /* No mappings found. Just use the old name */
144 *mapped_name = talloc_strdup(talloc_tos(), name_in);
145 if (!*mapped_name) {
146 errno = ENOMEM;
147 return NT_STATUS_NO_MEMORY;
149 return NT_STATUS_OK;
152 status = string_replace_allocate(conn,
153 name_in,
154 selected->mappings,
155 talloc_tos(),
156 mapped_name,
157 direction);
158 return status;
161 static int catia_connect(struct vfs_handle_struct *handle,
162 const char *service,
163 const char *user)
166 * Unless we have an async implementation of get_dos_attributes turn
167 * this off.
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,
176 const char *mask,
177 uint32_t attr)
179 char *name_mapped = NULL;
180 NTSTATUS status;
181 DIR *ret;
182 struct smb_filename *mapped_smb_fname = NULL;
184 status = catia_string_replace_allocate(handle->conn,
185 smb_fname->base_name,
186 &name_mapped,
187 vfs_translate_to_unix);
188 if (!NT_STATUS_IS_OK(status)) {
189 errno = map_errno_from_nt_status(status);
190 return NULL;
193 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
194 name_mapped,
195 NULL,
196 NULL,
197 smb_fname->flags);
198 if (mapped_smb_fname == NULL) {
199 TALLOC_FREE(mapped_smb_fname);
200 errno = ENOMEM;
201 return NULL;
204 ret = SMB_VFS_NEXT_OPENDIR(handle, mapped_smb_fname, mask, attr);
206 TALLOC_FREE(name_mapped);
207 TALLOC_FREE(mapped_smb_fname);
209 return ret;
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,
219 TALLOC_CTX *mem_ctx,
220 char **pmapped_name)
222 char *name = NULL;
223 char *mapped_name;
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);
233 if (!name) {
234 errno = ENOMEM;
235 return NT_STATUS_NO_MEMORY;
237 status = catia_string_replace_allocate(handle->conn, name,
238 &mapped_name, direction);
240 TALLOC_FREE(name);
241 if (!NT_STATUS_IS_OK(status)) {
242 return 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 */
251 ret = status;
252 } else {
253 TALLOC_FREE(mapped_name);
256 return ret;
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,
264 files_struct *fsp,
265 const char *location)
267 DEBUG(lvl, ("%s: cc [%p] cc->busy [%p] "
268 "is_fsp_ext [%s] "
269 "fsp [%p] fsp name [%s] "
270 "orig_fname [%s] "
271 "fname [%s] "
272 "orig_base_fname [%s] "
273 "base_fname [%s]\n",
274 location,
275 cc, cc->busy,
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,
284 files_struct *fsp)
286 struct catia_cache *cc = *_cc;
288 if (cc->is_fsp_ext) {
289 VFS_REMOVE_FSP_EXTENSION(handle, fsp);
290 cc = NULL;
291 } else {
292 TALLOC_FREE(cc);
295 *_cc = NULL;
298 static struct catia_cache *catia_validate_and_apply_cc(
299 vfs_handle_struct *handle,
300 files_struct *fsp,
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);
309 if (cc == NULL) {
310 return NULL;
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;
337 return NULL;
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);
346 return cc;
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);
363 return NULL;
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;
376 cc->busy = busy;
377 CATIA_DEBUG_CC(10, cc, fsp);
378 return cc;
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,
386 files_struct *fsp,
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;
393 NTSTATUS status;
394 bool make_tmp_cache = false;
396 *_cc = NULL;
398 DBG_DEBUG("Called from [%s]\n", function);
400 cc = catia_validate_and_apply_cc(handle,
401 fsp,
402 busy,
403 &make_tmp_cache);
404 if (cc != NULL) {
405 if (cc->busy != busy) {
406 return 0;
408 *_cc = cc;
409 return 0;
412 if (!make_tmp_cache) {
413 cc = VFS_ADD_FSP_EXTENSION(
414 handle, fsp, struct catia_cache, NULL);
415 if (cc == NULL) {
416 return -1;
418 *cc = (struct catia_cache) {
419 .is_fsp_ext = true,
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);
426 return -1;
428 } else {
429 cc = talloc_zero(mem_ctx, struct catia_cache);
430 if (cc == NULL) {
431 return -1;
433 mem_ctx = cc;
437 status = catia_string_replace_allocate(handle->conn,
438 fsp->fsp_name->base_name,
439 &cc->fname,
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);
444 return -1;
446 talloc_steal(mem_ctx, cc->fname);
448 if (fsp->base_fsp != NULL) {
449 status = catia_string_replace_allocate(
450 handle->conn,
451 fsp->base_fsp->fsp_name->base_name,
452 &cc->base_fname,
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);
457 return -1;
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;
470 cc->busy = busy;
471 CATIA_DEBUG_CC(10, cc, fsp);
473 *_cc = cc;
475 return 0;
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; \
482 } while(0)
484 static void catia_fetch_fsp_post_next(struct catia_cache **_cc,
485 files_struct *fsp,
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);
494 if (cc == NULL) {
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
498 * NULL.
500 return;
503 if (cc->busy != busy) {
504 CATIA_DEBUG_CC(0, cc, fsp);
505 smb_panic(__location__);
506 return;
509 cc->busy = NULL;
510 *_cc = NULL;
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) {
520 TALLOC_FREE(cc);
523 return;
526 static int catia_open(vfs_handle_struct *handle,
527 struct smb_filename *smb_fname,
528 files_struct *fsp,
529 int flags,
530 mode_t mode)
532 struct catia_cache *cc = NULL;
533 char *orig_smb_fname = smb_fname->base_name;
534 char *mapped_smb_fname = NULL;
535 NTSTATUS status;
536 int ret;
538 status = catia_string_replace_allocate(handle->conn,
539 smb_fname->base_name,
540 &mapped_smb_fname,
541 vfs_translate_to_unix);
542 if (!NT_STATUS_IS_OK(status)) {
543 return -1;
546 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
547 if (ret != 0) {
548 TALLOC_FREE(mapped_smb_fname);
549 return ret;
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);
559 return ret;
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;
571 NTSTATUS status;
572 int ret = -1;
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);
579 return -1;
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);
587 return -1;
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) {
593 errno = ENOMEM;
594 goto out;
597 smb_fname_dst_tmp = cp_smb_filename(ctx, smb_fname_dst);
598 if (smb_fname_dst_tmp == NULL) {
599 errno = ENOMEM;
600 goto out;
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,
611 smb_fname_dst_tmp);
612 out:
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);
617 return ret;
620 static int catia_stat(vfs_handle_struct *handle,
621 struct smb_filename *smb_fname)
623 char *name = NULL;
624 char *tmp_base_name;
625 int ret;
626 NTSTATUS status;
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);
633 return -1;
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;
642 TALLOC_FREE(name);
643 return ret;
646 static int catia_lstat(vfs_handle_struct *handle,
647 struct smb_filename *smb_fname)
649 char *name = NULL;
650 char *tmp_base_name;
651 int ret;
652 NTSTATUS status;
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);
659 return -1;
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;
667 TALLOC_FREE(name);
669 return ret;
672 static int catia_unlink(vfs_handle_struct *handle,
673 const struct smb_filename *smb_fname)
675 struct smb_filename *smb_fname_tmp = NULL;
676 char *name = NULL;
677 NTSTATUS status;
678 int ret;
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);
685 return -1;
688 /* Setup temporary smb_filename structs. */
689 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
690 if (smb_fname_tmp == NULL) {
691 errno = ENOMEM;
692 return -1;
695 smb_fname_tmp->base_name = name;
696 ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp);
697 TALLOC_FREE(smb_fname_tmp);
698 TALLOC_FREE(name);
700 return ret;
703 static int catia_chown(vfs_handle_struct *handle,
704 const struct smb_filename *smb_fname,
705 uid_t uid,
706 gid_t gid)
708 char *name = NULL;
709 NTSTATUS status;
710 int ret;
711 int saved_errno;
712 struct smb_filename *catia_smb_fname = NULL;
714 status = catia_string_replace_allocate(handle->conn,
715 smb_fname->base_name,
716 &name,
717 vfs_translate_to_unix);
718 if (!NT_STATUS_IS_OK(status)) {
719 errno = map_errno_from_nt_status(status);
720 return -1;
722 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
723 name,
724 NULL,
725 NULL,
726 smb_fname->flags);
727 if (catia_smb_fname == NULL) {
728 TALLOC_FREE(name);
729 errno = ENOMEM;
730 return -1;
733 ret = SMB_VFS_NEXT_CHOWN(handle, catia_smb_fname, uid, gid);
734 saved_errno = errno;
735 TALLOC_FREE(name);
736 TALLOC_FREE(catia_smb_fname);
737 errno = saved_errno;
738 return ret;
741 static int catia_lchown(vfs_handle_struct *handle,
742 const struct smb_filename *smb_fname,
743 uid_t uid,
744 gid_t gid)
746 char *name = NULL;
747 NTSTATUS status;
748 int ret;
749 int saved_errno;
750 struct smb_filename *catia_smb_fname = NULL;
752 status = catia_string_replace_allocate(handle->conn,
753 smb_fname->base_name,
754 &name,
755 vfs_translate_to_unix);
756 if (!NT_STATUS_IS_OK(status)) {
757 errno = map_errno_from_nt_status(status);
758 return -1;
760 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
761 name,
762 NULL,
763 NULL,
764 smb_fname->flags);
765 if (catia_smb_fname == NULL) {
766 TALLOC_FREE(name);
767 errno = ENOMEM;
768 return -1;
771 ret = SMB_VFS_NEXT_LCHOWN(handle, catia_smb_fname, uid, gid);
772 saved_errno = errno;
773 TALLOC_FREE(name);
774 TALLOC_FREE(catia_smb_fname);
775 errno = saved_errno;
776 return ret;
779 static int catia_chmod(vfs_handle_struct *handle,
780 const struct smb_filename *smb_fname,
781 mode_t mode)
783 char *name = NULL;
784 NTSTATUS status;
785 int ret;
786 int saved_errno;
787 struct smb_filename *catia_smb_fname = NULL;
789 status = catia_string_replace_allocate(handle->conn,
790 smb_fname->base_name,
791 &name,
792 vfs_translate_to_unix);
793 if (!NT_STATUS_IS_OK(status)) {
794 errno = map_errno_from_nt_status(status);
795 return -1;
797 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
798 name,
799 NULL,
800 NULL,
801 smb_fname->flags);
802 if (catia_smb_fname == NULL) {
803 TALLOC_FREE(name);
804 errno = ENOMEM;
805 return -1;
808 ret = SMB_VFS_NEXT_CHMOD(handle, catia_smb_fname, mode);
809 saved_errno = errno;
810 TALLOC_FREE(name);
811 TALLOC_FREE(catia_smb_fname);
812 errno = saved_errno;
813 return ret;
816 static int catia_rmdir(vfs_handle_struct *handle,
817 const struct smb_filename *smb_fname)
819 char *name = NULL;
820 NTSTATUS status;
821 int ret;
822 struct smb_filename *catia_smb_fname = NULL;
824 status = catia_string_replace_allocate(handle->conn,
825 smb_fname->base_name,
826 &name,
827 vfs_translate_to_unix);
828 if (!NT_STATUS_IS_OK(status)) {
829 errno = map_errno_from_nt_status(status);
830 return -1;
832 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
833 name,
834 NULL,
835 NULL,
836 smb_fname->flags);
837 if (catia_smb_fname == NULL) {
838 TALLOC_FREE(name);
839 errno = ENOMEM;
840 return -1;
843 ret = SMB_VFS_NEXT_RMDIR(handle, catia_smb_fname);
844 TALLOC_FREE(name);
845 TALLOC_FREE(catia_smb_fname);
847 return ret;
850 static int catia_mkdir(vfs_handle_struct *handle,
851 const struct smb_filename *smb_fname,
852 mode_t mode)
854 char *name = NULL;
855 NTSTATUS status;
856 int ret;
857 struct smb_filename *catia_smb_fname = NULL;
859 status = catia_string_replace_allocate(handle->conn,
860 smb_fname->base_name,
861 &name,
862 vfs_translate_to_unix);
863 if (!NT_STATUS_IS_OK(status)) {
864 errno = map_errno_from_nt_status(status);
865 return -1;
867 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
868 name,
869 NULL,
870 NULL,
871 smb_fname->flags);
872 if (catia_smb_fname == NULL) {
873 TALLOC_FREE(name);
874 errno = ENOMEM;
875 return -1;
878 ret = SMB_VFS_NEXT_MKDIR(handle, catia_smb_fname, mode);
879 TALLOC_FREE(name);
880 TALLOC_FREE(catia_smb_fname);
882 return ret;
885 static int catia_chdir(vfs_handle_struct *handle,
886 const struct smb_filename *smb_fname)
888 char *name = NULL;
889 struct smb_filename *catia_smb_fname = NULL;
890 NTSTATUS status;
891 int ret;
893 status = catia_string_replace_allocate(handle->conn,
894 smb_fname->base_name,
895 &name,
896 vfs_translate_to_unix);
897 if (!NT_STATUS_IS_OK(status)) {
898 errno = map_errno_from_nt_status(status);
899 return -1;
902 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
903 name,
904 NULL,
905 NULL,
906 smb_fname->flags);
907 if (catia_smb_fname == NULL) {
908 TALLOC_FREE(name);
909 errno = ENOMEM;
910 return -1;
912 ret = SMB_VFS_NEXT_CHDIR(handle, catia_smb_fname);
913 TALLOC_FREE(name);
914 TALLOC_FREE(catia_smb_fname);
916 return ret;
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;
924 char *name = NULL;
925 NTSTATUS status;
926 int ret;
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);
933 return -1;
936 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
937 if (smb_fname_tmp == NULL) {
938 errno = ENOMEM;
939 return -1;
942 smb_fname_tmp->base_name = name;
943 ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
944 TALLOC_FREE(name);
945 TALLOC_FREE(smb_fname_tmp);
947 return ret;
950 static struct smb_filename *
951 catia_realpath(vfs_handle_struct *handle,
952 TALLOC_CTX *ctx,
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;
958 NTSTATUS status;
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);
965 return NULL;
968 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
969 mapped_name,
970 NULL,
971 NULL,
972 smb_fname->flags);
973 if (catia_smb_fname == NULL) {
974 TALLOC_FREE(mapped_name);
975 errno = ENOMEM;
976 return NULL;
978 return_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, catia_smb_fname);
979 TALLOC_FREE(mapped_name);
980 TALLOC_FREE(catia_smb_fname);
981 return return_fname;
984 static int catia_chflags(struct vfs_handle_struct *handle,
985 const struct smb_filename *smb_fname,
986 unsigned int flags)
988 char *name = NULL;
989 struct smb_filename *catia_smb_fname = NULL;
990 NTSTATUS status;
991 int ret;
993 status = catia_string_replace_allocate(handle->conn,
994 smb_fname->base_name,
995 &name,
996 vfs_translate_to_unix);
997 if (!NT_STATUS_IS_OK(status)) {
998 errno = map_errno_from_nt_status(status);
999 return -1;
1001 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
1002 name,
1003 NULL,
1004 NULL,
1005 smb_fname->flags);
1006 if (catia_smb_fname == NULL) {
1007 TALLOC_FREE(name);
1008 errno = ENOMEM;
1009 return -1;
1012 ret = SMB_VFS_NEXT_CHFLAGS(handle, catia_smb_fname, flags);
1013 TALLOC_FREE(name);
1014 TALLOC_FREE(catia_smb_fname);
1016 return ret;
1019 static NTSTATUS
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;
1028 NTSTATUS status;
1029 unsigned int i;
1030 struct smb_filename *catia_smb_fname = NULL;
1031 unsigned int num_streams = 0;
1032 struct stream_struct *streams = NULL;
1034 *_num_streams = 0;
1035 *_streams = NULL;
1037 status = catia_string_replace_allocate(handle->conn,
1038 smb_fname->base_name,
1039 &mapped_name,
1040 vfs_translate_to_unix);
1041 if (!NT_STATUS_IS_OK(status)) {
1042 errno = map_errno_from_nt_status(status);
1043 return status;
1046 catia_smb_fname = synthetic_smb_fname(talloc_tos(),
1047 mapped_name,
1048 NULL,
1049 NULL,
1050 smb_fname->flags);
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)) {
1061 return 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';
1078 stream_type += 1;
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);
1085 return status;
1088 if (stream_type != NULL) {
1089 streams[i].name = talloc_asprintf(streams, ":%s:%s",
1090 mapped_name, stream_type);
1091 } else {
1092 streams[i].name = talloc_asprintf(streams, ":%s",
1093 mapped_name);
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;
1108 static NTSTATUS
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;
1118 NTSTATUS status;
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);
1124 return status;
1126 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1127 mapped_name,
1128 NULL,
1129 NULL,
1130 smb_fname->flags);
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);
1141 return status;
1144 static SMB_ACL_T
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;
1152 NTSTATUS status;
1153 SMB_ACL_T ret;
1154 int saved_errno = 0;
1156 status = catia_string_replace_allocate(handle->conn,
1157 smb_fname->base_name,
1158 &mapped_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(),
1166 mapped_name,
1167 NULL,
1168 NULL,
1169 smb_fname->flags);
1170 if (mapped_smb_fname == NULL) {
1171 TALLOC_FREE(mapped_name);
1172 errno = ENOMEM;
1173 return (SMB_ACL_T)NULL;
1176 ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, mapped_smb_fname,
1177 type, mem_ctx);
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;
1186 return ret;
1189 static int
1190 catia_sys_acl_set_file(vfs_handle_struct *handle,
1191 const struct smb_filename *smb_fname,
1192 SMB_ACL_TYPE_T type,
1193 SMB_ACL_T theacl)
1195 struct smb_filename *mapped_smb_fname = NULL;
1196 int saved_errno = 0;
1197 char *mapped_name = NULL;
1198 NTSTATUS status;
1199 int ret;
1201 status = catia_string_replace_allocate(handle->conn,
1202 smb_fname->base_name,
1203 &mapped_name,
1204 vfs_translate_to_unix);
1205 if (!NT_STATUS_IS_OK(status)) {
1206 errno = map_errno_from_nt_status(status);
1207 return -1;
1210 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1211 mapped_name,
1212 NULL,
1213 NULL,
1214 smb_fname->flags);
1215 if (mapped_smb_fname == NULL) {
1216 TALLOC_FREE(mapped_name);
1217 errno = ENOMEM;
1218 return -1;
1221 ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, mapped_smb_fname,
1222 type, theacl);
1223 if (ret == -1) {
1224 saved_errno = errno;
1226 TALLOC_FREE(mapped_smb_fname);
1227 TALLOC_FREE(mapped_name);
1228 if (saved_errno != 0) {
1229 errno = saved_errno;
1231 return ret;
1234 static int
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;
1241 NTSTATUS status;
1242 int ret;
1244 status = catia_string_replace_allocate(handle->conn,
1245 smb_fname->base_name,
1246 &mapped_name,
1247 vfs_translate_to_unix);
1248 if (!NT_STATUS_IS_OK(status)) {
1249 errno = map_errno_from_nt_status(status);
1250 return -1;
1253 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1254 mapped_name,
1255 NULL,
1256 NULL,
1257 smb_fname->flags);
1258 if (mapped_smb_fname == NULL) {
1259 TALLOC_FREE(mapped_name);
1260 errno = ENOMEM;
1261 return -1;
1263 ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, mapped_smb_fname);
1264 if (ret == -1) {
1265 saved_errno = errno;
1267 TALLOC_FREE(mapped_smb_fname);
1268 TALLOC_FREE(mapped_name);
1269 if (saved_errno != 0) {
1270 errno = saved_errno;
1272 return ret;
1275 static ssize_t
1276 catia_getxattr(vfs_handle_struct *handle,
1277 const struct smb_filename *smb_fname,
1278 const char *name,
1279 void *value,
1280 size_t size)
1282 struct smb_filename *mapped_smb_fname = NULL;
1283 char *mapped_name = NULL;
1284 char *mapped_ea_name = NULL;
1285 NTSTATUS status;
1286 ssize_t ret;
1287 int saved_errno = 0;
1289 status = catia_string_replace_allocate(handle->conn,
1290 smb_fname->base_name,
1291 &mapped_name,
1292 vfs_translate_to_unix);
1293 if (!NT_STATUS_IS_OK(status)) {
1294 errno = map_errno_from_nt_status(status);
1295 return -1;
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);
1303 return -1;
1306 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1307 mapped_name,
1308 NULL,
1309 NULL,
1310 smb_fname->flags);
1311 if (mapped_smb_fname == NULL) {
1312 TALLOC_FREE(mapped_name);
1313 TALLOC_FREE(mapped_ea_name);
1314 errno = ENOMEM;
1315 return -1;
1318 ret = SMB_VFS_NEXT_GETXATTR(handle, mapped_smb_fname,
1319 mapped_ea_name, value, size);
1320 if (ret == -1) {
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;
1330 return ret;
1333 static ssize_t
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;
1340 NTSTATUS status;
1341 ssize_t ret;
1342 int saved_errno = 0;
1344 status = catia_string_replace_allocate(handle->conn,
1345 smb_fname->base_name,
1346 &mapped_name,
1347 vfs_translate_to_unix);
1348 if (!NT_STATUS_IS_OK(status)) {
1349 errno = map_errno_from_nt_status(status);
1350 return -1;
1353 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1354 mapped_name,
1355 NULL,
1356 NULL,
1357 smb_fname->flags);
1358 if (mapped_smb_fname == NULL) {
1359 TALLOC_FREE(mapped_name);
1360 errno = ENOMEM;
1361 return -1;
1364 ret = SMB_VFS_NEXT_LISTXATTR(handle, mapped_smb_fname, list, size);
1365 if (ret == -1) {
1366 saved_errno = errno;
1368 TALLOC_FREE(mapped_name);
1369 TALLOC_FREE(mapped_smb_fname);
1370 if (saved_errno != 0) {
1371 errno = saved_errno;
1374 return ret;
1377 static int
1378 catia_removexattr(vfs_handle_struct *handle,
1379 const struct smb_filename *smb_fname,
1380 const char *name)
1382 struct smb_filename *mapped_smb_fname = NULL;
1383 char *mapped_name = NULL;
1384 char *mapped_ea_name = NULL;
1385 NTSTATUS status;
1386 ssize_t ret;
1387 int saved_errno = 0;
1389 status = catia_string_replace_allocate(handle->conn,
1390 smb_fname->base_name,
1391 &mapped_name,
1392 vfs_translate_to_unix);
1393 if (!NT_STATUS_IS_OK(status)) {
1394 errno = map_errno_from_nt_status(status);
1395 return -1;
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);
1403 return -1;
1406 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1407 mapped_name,
1408 NULL,
1409 NULL,
1410 smb_fname->flags);
1411 if (mapped_smb_fname == NULL) {
1412 TALLOC_FREE(mapped_name);
1413 TALLOC_FREE(mapped_ea_name);
1414 errno = ENOMEM;
1415 return -1;
1418 ret = SMB_VFS_NEXT_REMOVEXATTR(handle, mapped_smb_fname,
1419 mapped_ea_name);
1420 if (ret == -1) {
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;
1430 return ret;
1433 static int
1434 catia_setxattr(vfs_handle_struct *handle,
1435 const struct smb_filename *smb_fname,
1436 const char *name,
1437 const void *value,
1438 size_t size,
1439 int flags)
1441 struct smb_filename *mapped_smb_fname = NULL;
1442 char *mapped_name = NULL;
1443 char *mapped_ea_name = NULL;
1444 NTSTATUS status;
1445 ssize_t ret;
1446 int saved_errno = 0;
1448 status = catia_string_replace_allocate(handle->conn,
1449 smb_fname->base_name,
1450 &mapped_name,
1451 vfs_translate_to_unix);
1452 if (!NT_STATUS_IS_OK(status)) {
1453 errno = map_errno_from_nt_status(status);
1454 return -1;
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);
1462 return -1;
1465 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
1466 mapped_name,
1467 NULL,
1468 NULL,
1469 smb_fname->flags);
1470 if (mapped_smb_fname == NULL) {
1471 TALLOC_FREE(mapped_name);
1472 TALLOC_FREE(mapped_ea_name);
1473 errno = ENOMEM;
1474 return -1;
1477 ret = SMB_VFS_NEXT_SETXATTR(handle, mapped_smb_fname, mapped_ea_name,
1478 value, size, flags);
1479 if (ret == -1) {
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;
1489 return ret;
1492 static int catia_fstat(vfs_handle_struct *handle,
1493 files_struct *fsp,
1494 SMB_STRUCT_STAT *sbuf)
1496 struct catia_cache *cc = NULL;
1497 int ret;
1499 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1500 if (ret != 0) {
1501 return ret;
1504 ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
1506 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1508 return ret;
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;
1516 ssize_t result;
1517 int ret;
1519 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1520 if (ret != 0) {
1521 return ret;
1524 result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
1526 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1528 return result;
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;
1536 ssize_t result;
1537 int ret;
1539 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1540 if (ret != 0) {
1541 return ret;
1544 result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
1546 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1548 return result;
1551 static int catia_ftruncate(struct vfs_handle_struct *handle,
1552 struct files_struct *fsp,
1553 off_t offset)
1555 struct catia_cache *cc = NULL;
1556 int ret;
1558 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1559 if (ret != 0) {
1560 return ret;
1563 ret = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
1565 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1567 return ret;
1570 static int catia_fallocate(struct vfs_handle_struct *handle,
1571 struct files_struct *fsp,
1572 uint32_t mode,
1573 off_t offset,
1574 off_t len)
1576 struct catia_cache *cc = NULL;
1577 int ret;
1579 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1580 if (ret != 0) {
1581 return ret;
1584 ret = SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
1586 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1588 return ret;
1591 static ssize_t catia_fgetxattr(struct vfs_handle_struct *handle,
1592 struct files_struct *fsp,
1593 const char *name,
1594 void *value,
1595 size_t size)
1597 char *mapped_xattr_name = NULL;
1598 NTSTATUS status;
1599 ssize_t result;
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);
1606 return -1;
1609 result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, mapped_xattr_name,
1610 value, size);
1612 TALLOC_FREE(mapped_xattr_name);
1614 return result;
1617 static ssize_t catia_flistxattr(struct vfs_handle_struct *handle,
1618 struct files_struct *fsp,
1619 char *list,
1620 size_t size)
1622 struct catia_cache *cc = NULL;
1623 ssize_t result;
1624 int ret;
1626 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1627 if (ret != 0) {
1628 return ret;
1631 result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
1633 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1635 return result;
1638 static int catia_fremovexattr(struct vfs_handle_struct *handle,
1639 struct files_struct *fsp,
1640 const char *name)
1642 char *mapped_name = NULL;
1643 NTSTATUS status;
1644 int ret;
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);
1650 return -1;
1653 ret = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, mapped_name);
1655 TALLOC_FREE(mapped_name);
1657 return ret;
1660 static int catia_fsetxattr(struct vfs_handle_struct *handle,
1661 struct files_struct *fsp,
1662 const char *name,
1663 const void *value,
1664 size_t size,
1665 int flags)
1667 char *mapped_xattr_name = NULL;
1668 NTSTATUS status;
1669 int ret;
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);
1675 return -1;
1678 ret = SMB_VFS_NEXT_FSETXATTR(handle, fsp, mapped_xattr_name,
1679 value, size, flags);
1681 TALLOC_FREE(mapped_xattr_name);
1683 return ret;
1686 static SMB_ACL_T catia_sys_acl_get_fd(vfs_handle_struct *handle,
1687 files_struct *fsp,
1688 TALLOC_CTX *mem_ctx)
1690 struct catia_cache *cc = NULL;
1691 struct smb_acl_t *result = NULL;
1692 int ret;
1694 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1695 if (ret != 0) {
1696 return NULL;
1699 result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx);
1701 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1703 return result;
1706 static int catia_sys_acl_blob_get_fd(vfs_handle_struct *handle,
1707 files_struct *fsp,
1708 TALLOC_CTX *mem_ctx,
1709 char **blob_description,
1710 DATA_BLOB *blob)
1712 struct catia_cache *cc = NULL;
1713 int ret;
1715 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1716 if (ret != 0) {
1717 return ret;
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);
1725 return ret;
1728 static int catia_sys_acl_set_fd(vfs_handle_struct *handle,
1729 files_struct *fsp,
1730 SMB_ACL_T theacl)
1732 struct catia_cache *cc = NULL;
1733 int ret;
1735 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1736 if (ret != 0) {
1737 return ret;
1740 ret = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl);
1742 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1744 return ret;
1747 static NTSTATUS catia_fget_nt_acl(vfs_handle_struct *handle,
1748 files_struct *fsp,
1749 uint32_t security_info,
1750 TALLOC_CTX *mem_ctx,
1751 struct security_descriptor **ppdesc)
1753 struct catia_cache *cc = NULL;
1754 NTSTATUS status;
1755 int ret;
1757 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1758 if (ret != 0) {
1759 return map_nt_error_from_unix(errno);
1762 status = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info,
1763 mem_ctx, ppdesc);
1765 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1767 return status;
1770 static NTSTATUS catia_fset_nt_acl(vfs_handle_struct *handle,
1771 files_struct *fsp,
1772 uint32_t security_info_sent,
1773 const struct security_descriptor *psd)
1775 struct catia_cache *cc = NULL;
1776 NTSTATUS status;
1777 int ret;
1779 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1780 if (ret != 0) {
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);
1788 return status;
1791 static NTSTATUS catia_fset_dos_attributes(struct vfs_handle_struct *handle,
1792 struct files_struct *fsp,
1793 uint32_t dosmode)
1795 struct catia_cache *cc = NULL;
1796 NTSTATUS status;
1797 int ret;
1799 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1800 if (ret != 0) {
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);
1808 return status;
1811 static NTSTATUS catia_fget_dos_attributes(struct vfs_handle_struct *handle,
1812 struct files_struct *fsp,
1813 uint32_t *dosmode)
1815 struct catia_cache *cc = NULL;
1816 NTSTATUS status;
1817 int ret;
1819 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1820 if (ret != 0) {
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);
1828 return status;
1831 static int catia_fchown(vfs_handle_struct *handle,
1832 files_struct *fsp,
1833 uid_t uid,
1834 gid_t gid)
1836 struct catia_cache *cc = NULL;
1837 int ret;
1839 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1840 if (ret != 0) {
1841 return ret;
1844 ret = SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid);
1846 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1848 return ret;
1851 static int catia_fchmod(vfs_handle_struct *handle,
1852 files_struct *fsp,
1853 mode_t mode)
1855 struct catia_cache *cc = NULL;
1856 int ret;
1858 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
1859 if (ret != 0) {
1860 return ret;
1863 ret = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
1865 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
1867 return ret;
1870 struct catia_pread_state {
1871 ssize_t ret;
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,
1883 void *data,
1884 size_t n,
1885 off_t offset)
1887 struct tevent_req *req = NULL, *subreq = NULL;
1888 struct catia_pread_state *state = NULL;
1889 int ret;
1891 req = tevent_req_create(mem_ctx, &state,
1892 struct catia_pread_state);
1893 if (req == NULL) {
1894 return NULL;
1896 state->fsp = fsp;
1898 ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
1899 if (ret != 0) {
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,
1905 n, offset);
1906 if (tevent_req_nomem(subreq, req)) {
1907 return tevent_req_post(req, ev);
1909 tevent_req_set_callback(subreq, catia_pread_done, req);
1911 return 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)) {
1936 return -1;
1939 *vfs_aio_state = state->vfs_aio_state;
1940 return state->ret;
1943 struct catia_pwrite_state {
1944 ssize_t ret;
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,
1956 const void *data,
1957 size_t n,
1958 off_t offset)
1960 struct tevent_req *req = NULL, *subreq = NULL;
1961 struct catia_pwrite_state *state = NULL;
1962 int ret;
1964 req = tevent_req_create(mem_ctx, &state,
1965 struct catia_pwrite_state);
1966 if (req == NULL) {
1967 return NULL;
1969 state->fsp = fsp;
1971 ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
1972 if (ret != 0) {
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,
1978 n, offset);
1979 if (tevent_req_nomem(subreq, req)) {
1980 return tevent_req_post(req, ev);
1982 tevent_req_set_callback(subreq, catia_pwrite_done, req);
1984 return 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)) {
2009 return -1;
2012 *vfs_aio_state = state->vfs_aio_state;
2013 return state->ret;
2016 static off_t catia_lseek(vfs_handle_struct *handle,
2017 files_struct *fsp,
2018 off_t offset,
2019 int whence)
2021 struct catia_cache *cc = NULL;
2022 ssize_t result;
2023 int ret;
2025 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2026 if (ret != 0) {
2027 return -1;
2030 result = SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence);
2032 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2034 return result;
2037 struct catia_fsync_state {
2038 int ret;
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;
2053 int ret;
2055 req = tevent_req_create(mem_ctx, &state,
2056 struct catia_fsync_state);
2057 if (req == NULL) {
2058 return NULL;
2060 state->fsp = fsp;
2062 ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
2063 if (ret != 0) {
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);
2074 return 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)) {
2099 return -1;
2102 *vfs_aio_state = state->vfs_aio_state;
2103 return state->ret;
2106 static bool catia_lock(vfs_handle_struct *handle,
2107 files_struct *fsp,
2108 int op,
2109 off_t offset,
2110 off_t count,
2111 int type)
2113 struct catia_cache *cc = NULL;
2114 bool ok;
2115 int ret;
2117 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2118 if (ret != 0) {
2119 return -1;
2122 ok = SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type);
2124 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2126 return ok;
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;
2135 int ret;
2137 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2138 if (ret != 0) {
2139 return -1;
2142 ret = SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, share_mode, access_mask);
2144 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2146 return ret;
2149 static int catia_linux_setlease(vfs_handle_struct *handle,
2150 files_struct *fsp,
2151 int leasetype)
2153 struct catia_cache *cc = NULL;
2154 int ret;
2156 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2157 if (ret != 0) {
2158 return -1;
2161 ret = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype);
2163 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2165 return ret;
2168 static bool catia_getlock(vfs_handle_struct *handle,
2169 files_struct *fsp,
2170 off_t *poffset,
2171 off_t *pcount,
2172 int *ptype,
2173 pid_t *ppid)
2175 struct catia_cache *cc = NULL;
2176 int ret;
2177 bool ok;
2179 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2180 if (ret != 0) {
2181 return -1;
2184 ok = SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid);
2186 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2188 return ok;
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;
2196 int ret;
2197 bool ok;
2199 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2200 if (ret != 0) {
2201 return -1;
2204 ok = SMB_VFS_NEXT_STRICT_LOCK_CHECK(handle, fsp, plock);
2206 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2208 return ok;
2211 static NTSTATUS catia_fsctl(struct vfs_handle_struct *handle,
2212 struct files_struct *fsp,
2213 TALLOC_CTX *ctx,
2214 uint32_t function,
2215 uint16_t req_flags,
2216 const uint8_t *_in_data,
2217 uint32_t in_len,
2218 uint8_t **_out_data,
2219 uint32_t max_out_len,
2220 uint32_t *out_len)
2222 NTSTATUS result;
2223 struct catia_cache *cc = NULL;
2224 int ret;
2226 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2227 if (ret != 0) {
2228 return map_nt_error_from_unix(errno);
2231 result = SMB_VFS_NEXT_FSCTL(handle,
2232 fsp,
2233 ctx,
2234 function,
2235 req_flags,
2236 _in_data,
2237 in_len,
2238 _out_data,
2239 max_out_len,
2240 out_len);
2242 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2244 return result;
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)
2253 NTSTATUS result;
2254 struct catia_cache *cc = NULL;
2255 int ret;
2256 struct smb_filename *mapped_smb_fname = NULL;
2257 char *mapped_name = NULL;
2259 if (fsp != NULL) {
2260 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2261 if (ret != 0) {
2262 return map_nt_error_from_unix(errno);
2264 mapped_smb_fname = fsp->fsp_name;
2265 } else {
2266 result = catia_string_replace_allocate(handle->conn,
2267 smb_fname->base_name,
2268 &mapped_name,
2269 vfs_translate_to_unix);
2270 if (!NT_STATUS_IS_OK(result)) {
2271 return result;
2274 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
2275 mapped_name,
2276 NULL,
2277 NULL,
2278 smb_fname->flags);
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,
2288 mem_ctx,
2289 fsp,
2290 mapped_smb_fname,
2291 _compression_fmt);
2293 if (fsp != NULL) {
2294 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2295 } else {
2296 TALLOC_FREE(mapped_smb_fname);
2299 return result;
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)
2307 NTSTATUS result;
2308 struct catia_cache *cc = NULL;
2309 int ret;
2311 ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
2312 if (ret != 0) {
2313 return map_nt_error_from_unix(errno);
2316 result = SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp,
2317 compression_fmt);
2319 CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
2321 return result;
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;
2330 char *fname = NULL;
2331 NTSTATUS status;
2333 status = catia_string_replace_allocate(handle->conn,
2334 smb_fname_in->base_name,
2335 &fname,
2336 vfs_translate_to_unix);
2337 if (!NT_STATUS_IS_OK(status)) {
2338 errno = map_errno_from_nt_status(status);
2339 return 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);
2348 TALLOC_FREE(fname);
2349 return status;
2352 static NTSTATUS catia_get_dos_attributes(struct vfs_handle_struct *handle,
2353 struct smb_filename *smb_fname,
2354 uint32_t *dosmode)
2356 char *mapped_name = NULL;
2357 const char *path = smb_fname->base_name;
2358 struct smb_filename *mapped_smb_fname = NULL;
2359 NTSTATUS status;
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);
2365 return status;
2367 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
2368 mapped_name,
2369 NULL,
2370 NULL,
2371 smb_fname->flags);
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,
2378 mapped_smb_fname,
2379 dosmode);
2380 TALLOC_FREE(mapped_name);
2381 TALLOC_FREE(mapped_smb_fname);
2383 return status;
2386 static NTSTATUS catia_set_dos_attributes(struct vfs_handle_struct *handle,
2387 const struct smb_filename *smb_fname,
2388 uint32_t dosmode)
2390 char *mapped_name = NULL;
2391 const char *path = smb_fname->base_name;
2392 struct smb_filename *mapped_smb_fname = NULL;
2393 NTSTATUS status;
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);
2399 return status;
2401 mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
2402 mapped_name,
2403 NULL,
2404 NULL,
2405 smb_fname->flags);
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,
2412 mapped_smb_fname,
2413 dosmode);
2414 TALLOC_FREE(mapped_name);
2415 TALLOC_FREE(mapped_smb_fname);
2417 return status;
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,
2499 static_decl_vfs;
2500 NTSTATUS vfs_catia_init(TALLOC_CTX *ctx)
2502 NTSTATUS ret;
2504 ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "catia",
2505 &vfs_catia_fns);
2506 if (!NT_STATUS_IS_OK(ret))
2507 return 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 "
2513 "class!\n"));
2514 } else {
2515 DEBUG(10, ("vfs_catia: Debug class number of "
2516 "'catia': %d\n", vfs_catia_debug_level));
2519 return ret;