s3:vfs_catia: Use talloc_zero for simplification
[Samba/aatanasov.git] / source3 / modules / vfs_catia.c
blob279ab596fbacb3adb4e24f60988b2b1863a9782e
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 * Yes, this a BAD BAD UGLY INCOMPLETE hack, but it helps quite some people
8 * out there. Catia V4 on AIX uses characters like "<*$ a *lot*, all forbidden
9 * under Windows...
11 * Copyright (C) Volker Lendecke, 2005
12 * Copyright (C) Aravind Srinivasan, 2009
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see <http://www.gnu.org/licenses/>.
29 #include "includes.h"
31 #define TO_UNIX 0
32 #define TO_WINDOWS 1
34 #define GLOBAL_SNUM 0xFFFFFFF
35 #define MAP_SIZE 0xFF
36 #define MAP_NUM 0x101 /* max unicode charval / MAP_SIZE */
37 #define T_OFFSET(_v_) ((_v_ % MAP_SIZE))
38 #define T_START(_v_) (((_v_ / MAP_SIZE) * MAP_SIZE))
39 #define T_PICK(_v_) ((_v_ / MAP_SIZE))
41 struct char_mappings {
42 smb_ucs2_t entry[MAP_SIZE][2];
45 struct share_mapping_entry {
46 int snum;
47 struct share_mapping_entry *next;
48 struct char_mappings **mappings;
51 struct share_mapping_entry *srt_head = NULL;
53 static bool build_table(struct char_mappings **cmaps, int value)
55 int i;
56 int start = T_START(value);
58 (*cmaps) = talloc_zero(NULL, struct char_mappings);
60 if (!*cmaps)
61 return False;
63 for (i = 0; i < MAP_SIZE;i++) {
64 (*cmaps)->entry[i][TO_UNIX] = start + i;
65 (*cmaps)->entry[i][TO_WINDOWS] = start + i;
68 return True;
71 static void set_tables(struct char_mappings **cmaps,
72 long unix_map,
73 long windows_map)
75 int i;
77 /* set unix -> windows */
78 i = T_OFFSET(unix_map);
79 cmaps[T_PICK(unix_map)]->entry[i][TO_WINDOWS] = windows_map;
81 /* set windows -> unix */
82 i = T_OFFSET(windows_map);
83 cmaps[T_PICK(windows_map)]->entry[i][TO_UNIX] = unix_map;
86 static bool build_ranges(struct char_mappings **cmaps,
87 long unix_map,
88 long windows_map)
91 if (!cmaps[T_PICK(unix_map)]) {
92 if (!build_table(&cmaps[T_PICK(unix_map)], unix_map))
93 return False;
96 if (!cmaps[T_PICK(windows_map)]) {
97 if (!build_table(&cmaps[T_PICK(windows_map)], windows_map))
98 return False;
101 set_tables(cmaps, unix_map, windows_map);
103 return True;
106 struct share_mapping_entry *get_srt(connection_struct *conn,
107 struct share_mapping_entry **global)
109 struct share_mapping_entry *share;
111 for (share = srt_head; share != NULL; share = share->next) {
112 if (share->snum == GLOBAL_SNUM)
113 (*global) = share;
115 if (share->snum == SNUM(conn))
116 return share;
119 return share;
122 struct share_mapping_entry *add_srt(int snum, const char **mappings)
125 char *tmp;
126 fstring mapping;
127 int i;
128 long unix_map, windows_map;
129 struct share_mapping_entry *ret = NULL;
131 ret = (struct share_mapping_entry *)
132 TALLOC_ZERO(NULL, sizeof(struct share_mapping_entry) +
133 (mappings ? (MAP_NUM * sizeof(struct char_mappings *)) : 0));
135 if (!ret)
136 return ret;
138 ret->snum = snum;
140 if (mappings) {
141 ret->mappings = (struct char_mappings**) ((unsigned char*) ret +
142 sizeof(struct share_mapping_entry));
143 memset(ret->mappings, 0,
144 MAP_NUM * sizeof(struct char_mappings *));
145 } else {
146 ret->mappings = NULL;
147 return ret;
151 * catia mappings are of the form :
152 * UNIX char (in 0xnn hex) : WINDOWS char (in 0xnn hex)
154 * multiple mappings are comma seperated in smb.conf
156 for (i=0;mappings[i];i++) {
157 fstrcpy(mapping, mappings[i]);
158 unix_map = strtol(mapping, &tmp, 16);
159 if (unix_map == 0 && errno == EINVAL) {
160 DEBUG(0, ("INVALID CATIA MAPPINGS - %s\n", mapping));
161 continue;
163 windows_map = strtol(++tmp, NULL, 16);
164 if (windows_map == 0 && errno == EINVAL) {
165 DEBUG(0, ("INVALID CATIA MAPPINGS - %s\n", mapping));
166 continue;
169 if (!build_ranges(ret->mappings, unix_map, windows_map)) {
170 DEBUG(0, ("TABLE ERROR - CATIA MAPPINGS - %s\n", mapping));
171 continue;
175 ret->next = srt_head;
176 srt_head = ret;
178 return ret;
181 static bool init_mappings(connection_struct *conn,
182 struct share_mapping_entry **selected_out)
184 const char **mappings = NULL;
185 struct share_mapping_entry *share_level = NULL;
186 struct share_mapping_entry *global = NULL;
188 /* check srt cache */
189 share_level = get_srt(conn, &global);
190 if (share_level) {
191 *selected_out = share_level;
192 return (share_level->mappings != NULL);
195 /* see if we have a global setting */
196 if (!global) {
197 /* global setting */
198 mappings = lp_parm_string_list(-1, "catia", "mappings", NULL);
199 global = add_srt(GLOBAL_SNUM, mappings);
202 /* no global setting - what about share level ? */
203 mappings = lp_parm_string_list(SNUM(conn), "catia", "mappings", NULL);
204 share_level = add_srt(SNUM(conn), mappings);
206 if (share_level->mappings) {
207 (*selected_out) = share_level;
208 return True;
209 } else if (global->mappings) {
210 share_level->mappings = global->mappings;
211 (*selected_out) = share_level;
212 return True;
215 return False;
218 static NTSTATUS catia_string_replace_allocate(connection_struct *conn,
219 const char *name_in,
220 char **mapped_name,
221 int direction)
223 static smb_ucs2_t *tmpbuf = NULL;
224 smb_ucs2_t *ptr;
225 struct share_mapping_entry *selected;
226 struct char_mappings *map = NULL;
227 size_t converted_size;
228 TALLOC_CTX *ctx = talloc_tos();
230 if (!init_mappings(conn, &selected))
231 return NT_STATUS_OK;
233 if ((push_ucs2_talloc(ctx, &tmpbuf, name_in,
234 &converted_size)) == -1) {
235 return map_nt_error_from_unix(errno);
237 ptr = tmpbuf;
238 for(;*ptr;ptr++) {
239 if (*ptr == 0)
240 break;
241 map = selected->mappings[T_PICK((*ptr))];
243 /* nothing to do */
244 if (!map)
245 continue;
247 *ptr = map->entry[T_OFFSET((*ptr))][direction];
250 if ((pull_ucs2_talloc(ctx, mapped_name, tmpbuf,
251 &converted_size)) == -1) {
252 TALLOC_FREE(tmpbuf);
253 return map_nt_error_from_unix(errno);
255 TALLOC_FREE(tmpbuf);
256 return NT_STATUS_OK;
259 static SMB_STRUCT_DIR *catia_opendir(vfs_handle_struct *handle,
260 const char *fname,
261 const char *mask,
262 uint32 attr)
264 char *name_mapped = NULL;
265 NTSTATUS status;
266 SMB_STRUCT_DIR *ret;
268 status = catia_string_replace_allocate(handle->conn, fname,
269 &name_mapped, TO_UNIX);
270 if (!NT_STATUS_IS_OK(status)) {
271 errno = map_errno_from_nt_status(status);
272 return NULL;
275 ret = SMB_VFS_NEXT_OPENDIR(handle, name_mapped, mask, attr);
276 TALLOC_FREE(name_mapped);
278 return ret;
282 * TRANSLATE_NAME call which converts the given name to
283 * "WINDOWS displayable" name
285 static NTSTATUS catia_translate_name(vfs_handle_struct *handle,
286 char **mapped_name)
288 char *name = NULL;
289 NTSTATUS ret;
292 * Copy the supplied name and free the memory for mapped_name,
293 * already allocated by the caller.
294 * We will be allocating new memory for mapped_name in
295 * catia_string_replace_allocate
297 name = talloc_strdup(talloc_tos(), *mapped_name);
298 if (!name) {
299 errno = ENOMEM;
300 return NT_STATUS_NO_MEMORY;
302 TALLOC_FREE(*mapped_name);
303 ret = catia_string_replace_allocate(handle->conn, name,
304 mapped_name, TO_WINDOWS);
306 TALLOC_FREE(name);
307 if (!NT_STATUS_IS_OK(ret)) {
308 return ret;
311 ret = SMB_VFS_NEXT_TRANSLATE_NAME(handle, mapped_name);
313 return ret;
316 static int catia_open(vfs_handle_struct *handle,
317 struct smb_filename *smb_fname,
318 files_struct *fsp,
319 int flags,
320 mode_t mode)
322 char *name_mapped = NULL;
323 char *tmp_base_name;
324 int ret;
325 NTSTATUS status;
327 tmp_base_name = smb_fname->base_name;
328 status = catia_string_replace_allocate(handle->conn,
329 smb_fname->base_name,
330 &name_mapped, TO_UNIX);
331 if (!NT_STATUS_IS_OK(status)) {
332 errno = map_errno_from_nt_status(status);
333 return -1;
336 smb_fname->base_name = name_mapped;
337 ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
338 smb_fname->base_name = tmp_base_name;
339 TALLOC_FREE(name_mapped);
341 return ret;
344 /* @internal - Isilon create file support */
345 static NTSTATUS catia_createfile(vfs_handle_struct *handle,
346 struct smb_request *req,
347 uint16_t root_dir_fid,
348 struct smb_filename *smb_fname,
349 uint32_t access_mask,
350 uint32_t share_access,
351 uint32_t create_disposition,
352 uint32_t create_options,
353 uint32_t file_attributes,
354 uint32_t oplock_request,
355 uint64_t allocation_size,
356 struct security_descriptor *sd,
357 struct ea_list *ea_list,
358 files_struct **result,
359 int *pinfo)
361 char *name_mapped = NULL;
362 char *tmp_base_name;
363 NTSTATUS ret;
365 ret = catia_string_replace_allocate(handle->conn, smb_fname->base_name,
366 &name_mapped, TO_UNIX);
367 if (!NT_STATUS_IS_OK(ret)) {
368 errno = map_errno_from_nt_status(ret);
369 return ret;
372 tmp_base_name = smb_fname->base_name;
373 DEBUG(5, ("catia_createfile converted %s->%s (orginally %s)\n",
374 tmp_base_name, name_mapped, tmp_base_name));
375 smb_fname->base_name = name_mapped;
376 ret = SMB_VFS_NEXT_CREATE_FILE(handle, req, root_dir_fid,
377 smb_fname, access_mask, share_access,
378 create_disposition, create_options,
379 file_attributes, oplock_request,
380 allocation_size, sd, ea_list,
381 result, pinfo);
383 smb_fname->base_name = tmp_base_name;
384 TALLOC_FREE(name_mapped);
386 return ret;
389 static int catia_rename(vfs_handle_struct *handle,
390 const struct smb_filename *smb_fname_src,
391 const struct smb_filename *smb_fname_dst)
393 TALLOC_CTX *ctx = talloc_tos();
394 struct smb_filename *smb_fname_src_tmp = NULL;
395 struct smb_filename *smb_fname_dst_tmp = NULL;
396 NTSTATUS status;
397 int ret = -1;
399 status = catia_string_replace_allocate(handle->conn,
400 smb_fname_src->base_name,
401 &(smb_fname_src_tmp->base_name), TO_UNIX);
402 if (!NT_STATUS_IS_OK(status)) {
403 errno = map_errno_from_nt_status(status);
404 return -1;
407 status = catia_string_replace_allocate(handle->conn,
408 smb_fname_dst->base_name,
409 &(smb_fname_dst_tmp->base_name), TO_UNIX);
410 if (!NT_STATUS_IS_OK(status)) {
411 errno = map_errno_from_nt_status(status);
412 return -1;
415 /* Setup temporary smb_filename structs. */
416 status = copy_smb_filename(ctx, smb_fname_src, &smb_fname_src_tmp);
418 if (!NT_STATUS_IS_OK(status)) {
419 errno = map_errno_from_nt_status(status);
420 goto out;
423 status = copy_smb_filename(ctx, smb_fname_dst, &smb_fname_dst_tmp);
424 if (!NT_STATUS_IS_OK(status)) {
425 errno = map_errno_from_nt_status(status);
426 goto out;
429 DEBUG(10, ("converted old name: %s\n",
430 smb_fname_str_dbg(smb_fname_src_tmp)));
431 DEBUG(10, ("converted new name: %s\n",
432 smb_fname_str_dbg(smb_fname_dst_tmp)));
434 ret = SMB_VFS_NEXT_RENAME(handle, smb_fname_src_tmp,
435 smb_fname_dst_tmp);
436 out:
437 TALLOC_FREE(smb_fname_src_tmp);
438 TALLOC_FREE(smb_fname_dst_tmp);
439 return ret;
442 static int catia_stat(vfs_handle_struct *handle,
443 struct smb_filename *smb_fname)
445 char *name = NULL;
446 char *tmp_base_name;
447 int ret;
448 NTSTATUS status;
450 status = catia_string_replace_allocate(handle->conn,
451 smb_fname->base_name,
452 &name, TO_UNIX);
453 if (!NT_STATUS_IS_OK(status)) {
454 errno = map_errno_from_nt_status(status);
455 return -1;
458 tmp_base_name = smb_fname->base_name;
459 smb_fname->base_name = name;
461 ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
462 smb_fname->base_name = tmp_base_name;
464 TALLOC_FREE(name);
465 return ret;
468 static int catia_lstat(vfs_handle_struct *handle,
469 struct smb_filename *smb_fname)
471 char *name = NULL;
472 char *tmp_base_name;
473 int ret;
474 NTSTATUS status;
476 status = catia_string_replace_allocate(handle->conn,
477 smb_fname->base_name,
478 &name, TO_UNIX);
479 if (!NT_STATUS_IS_OK(status)) {
480 errno = map_errno_from_nt_status(status);
481 return -1;
484 tmp_base_name = smb_fname->base_name;
485 smb_fname->base_name = name;
487 ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
488 smb_fname->base_name = tmp_base_name;
489 TALLOC_FREE(name);
491 return ret;
494 static int catia_unlink(vfs_handle_struct *handle,
495 const struct smb_filename *smb_fname)
497 struct smb_filename *smb_fname_tmp = NULL;
498 char *name = NULL;
499 NTSTATUS status;
500 int ret;
502 status = catia_string_replace_allocate(handle->conn,
503 smb_fname->base_name,
504 &name, TO_UNIX);
505 if (!NT_STATUS_IS_OK(status)) {
506 errno = map_errno_from_nt_status(status);
507 return -1;
510 /* Setup temporary smb_filename structs. */
511 status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp);
512 if (!NT_STATUS_IS_OK(status)) {
513 errno = map_errno_from_nt_status(status);
514 return -1;
517 smb_fname_tmp->base_name = name;
518 ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp);
519 TALLOC_FREE(smb_fname_tmp);
520 TALLOC_FREE(name);
522 return ret;
525 static int catia_chown(vfs_handle_struct *handle,
526 const char *path,
527 uid_t uid,
528 gid_t gid)
530 char *name = NULL;
531 NTSTATUS status;
532 int ret;
534 status = catia_string_replace_allocate(handle->conn, path,
535 &name, TO_UNIX);
536 if (!NT_STATUS_IS_OK(status)) {
537 errno = map_errno_from_nt_status(status);
538 return -1;
541 ret = SMB_VFS_NEXT_CHOWN(handle, name, uid, gid);
542 TALLOC_FREE(name);
544 return ret;
547 static int catia_lchown(vfs_handle_struct *handle,
548 const char *path,
549 uid_t uid,
550 gid_t gid)
552 char *name = NULL;
553 NTSTATUS status;
554 int ret;
556 status = catia_string_replace_allocate(handle->conn, path,
557 &name, TO_UNIX);
558 if (!NT_STATUS_IS_OK(status)) {
559 errno = map_errno_from_nt_status(status);
560 return -1;
563 ret = SMB_VFS_NEXT_LCHOWN(handle, name, uid, gid);
564 TALLOC_FREE(name);
566 return ret;
569 static int catia_rmdir(vfs_handle_struct *handle,
570 const char *path)
572 char *name = NULL;
573 NTSTATUS status;
574 int ret;
576 status = catia_string_replace_allocate(handle->conn, path,
577 &name, TO_UNIX);
578 if (!NT_STATUS_IS_OK(status)) {
579 errno = map_errno_from_nt_status(status);
580 return -1;
583 ret = SMB_VFS_NEXT_RMDIR(handle, name);
584 TALLOC_FREE(name);
586 return ret;
589 static int catia_mkdir(vfs_handle_struct *handle,
590 const char *path,
591 mode_t mode)
593 char *name = NULL;
594 NTSTATUS status;
595 int ret;
597 status = catia_string_replace_allocate(handle->conn, path,
598 &name, TO_UNIX);
599 if (!NT_STATUS_IS_OK(status)) {
600 errno = map_errno_from_nt_status(status);
601 return -1;
604 ret = SMB_VFS_NEXT_MKDIR(handle, name, mode);
605 TALLOC_FREE(name);
607 return ret;
610 static int catia_chdir(vfs_handle_struct *handle,
611 const char *path)
613 char *name = NULL;
614 NTSTATUS status;
615 int ret;
617 status = catia_string_replace_allocate(handle->conn, path,
618 &name, TO_UNIX);
619 if (!NT_STATUS_IS_OK(status)) {
620 errno = map_errno_from_nt_status(status);
621 return -1;
624 ret = SMB_VFS_NEXT_CHDIR(handle, name);
625 TALLOC_FREE(name);
627 return ret;
630 static int catia_ntimes(vfs_handle_struct *handle,
631 const struct smb_filename *smb_fname,
632 struct smb_file_time *ft)
634 struct smb_filename *smb_fname_tmp = NULL;
635 char *name = NULL;
636 NTSTATUS status;
637 int ret;
639 status = catia_string_replace_allocate(handle->conn,
640 smb_fname->base_name,
641 &name, TO_UNIX);
642 if (!NT_STATUS_IS_OK(status)) {
643 errno = map_errno_from_nt_status(status);
644 return -1;
647 status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp);
648 if (!NT_STATUS_IS_OK(status)) {
649 errno = map_errno_from_nt_status(status);
650 return -1;
653 smb_fname_tmp->base_name = name;
654 ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
655 TALLOC_FREE(smb_fname_tmp);
657 return ret;
660 static char *
661 catia_realpath(vfs_handle_struct *handle, const char *path,
662 char *resolved_path)
664 char *mapped_name = NULL;
665 NTSTATUS status;
666 char *ret = NULL;
668 status = catia_string_replace_allocate(handle->conn, path,
669 &mapped_name, TO_UNIX);
670 if (!NT_STATUS_IS_OK(status)) {
671 errno = map_errno_from_nt_status(status);
672 return NULL;
675 ret = SMB_VFS_NEXT_REALPATH(handle, mapped_name, resolved_path);
676 TALLOC_FREE(mapped_name);
678 return ret;
681 static int catia_chflags(struct vfs_handle_struct *handle,
682 const char *path, unsigned int flags)
684 char *mapped_name = NULL;
685 NTSTATUS status;
686 int ret;
688 status = catia_string_replace_allocate(handle->conn, path,
689 &mapped_name, TO_UNIX);
690 if (!NT_STATUS_IS_OK(status)) {
691 errno = map_errno_from_nt_status(status);
692 return -1;
695 ret = SMB_VFS_NEXT_CHFLAGS(handle, mapped_name, flags);
696 TALLOC_FREE(mapped_name);
698 return ret;
701 static NTSTATUS
702 catia_streaminfo(struct vfs_handle_struct *handle,
703 struct files_struct *fsp,
704 const char *path,
705 TALLOC_CTX *mem_ctx,
706 unsigned int *num_streams,
707 struct stream_struct **streams)
709 char *mapped_name = NULL;
710 NTSTATUS status;
712 status = catia_string_replace_allocate(handle->conn, path,
713 &mapped_name, TO_UNIX);
714 if (!NT_STATUS_IS_OK(status)) {
715 errno = map_errno_from_nt_status(status);
716 return status;
719 status = SMB_VFS_NEXT_STREAMINFO(handle, fsp, mapped_name,
720 mem_ctx, num_streams,streams);
721 TALLOC_FREE(mapped_name);
723 return status;
726 static NTSTATUS
727 catia_get_nt_acl(struct vfs_handle_struct *handle,
728 const char *path,
729 uint32 security_info,
730 struct security_descriptor **ppdesc)
732 char *mapped_name = NULL;
733 NTSTATUS status;
735 status = catia_string_replace_allocate(handle->conn,
736 path, &mapped_name, TO_UNIX);
737 if (!NT_STATUS_IS_OK(status)) {
738 errno = map_errno_from_nt_status(status);
739 return status;
741 status = SMB_VFS_NEXT_GET_NT_ACL(handle, mapped_name,
742 security_info, ppdesc);
743 TALLOC_FREE(mapped_name);
745 return status;
748 static int
749 catia_chmod_acl(vfs_handle_struct *handle,
750 const char *path,
751 mode_t mode)
753 char *mapped_name = NULL;
754 NTSTATUS status;
755 int ret;
757 status = catia_string_replace_allocate(handle->conn,
758 path, &mapped_name, TO_UNIX);
759 if (!NT_STATUS_IS_OK(status)) {
760 errno = map_errno_from_nt_status(status);
761 return -1;
764 ret = SMB_VFS_NEXT_CHMOD_ACL(handle, mapped_name, mode);
765 TALLOC_FREE(mapped_name);
766 return ret;
769 static SMB_ACL_T
770 catia_sys_acl_get_file(vfs_handle_struct *handle,
771 const char *path,
772 SMB_ACL_TYPE_T type)
774 char *mapped_name = NULL;
775 NTSTATUS status;
776 SMB_ACL_T ret;
778 status = catia_string_replace_allocate(handle->conn,
779 path, &mapped_name, TO_UNIX);
780 if (!NT_STATUS_IS_OK(status)) {
781 errno = map_errno_from_nt_status(status);
782 return NULL;
785 ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, mapped_name, type);
786 TALLOC_FREE(mapped_name);
788 return ret;
791 static int
792 catia_sys_acl_set_file(vfs_handle_struct *handle,
793 const char *path,
794 SMB_ACL_TYPE_T type,
795 SMB_ACL_T theacl)
797 char *mapped_name = NULL;
798 NTSTATUS status;
799 int ret;
801 status = catia_string_replace_allocate(handle->conn,
802 path, &mapped_name, TO_UNIX);
803 if (!NT_STATUS_IS_OK(status)) {
804 errno = map_errno_from_nt_status(status);
805 return -1;
808 ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, mapped_name, type, theacl);
809 TALLOC_FREE(mapped_name);
811 return ret;
814 static int
815 catia_sys_acl_delete_def_file(vfs_handle_struct *handle,
816 const char *path)
818 char *mapped_name = NULL;
819 NTSTATUS status;
820 int ret;
822 status = catia_string_replace_allocate(handle->conn,
823 path, &mapped_name, TO_UNIX);
824 if (!NT_STATUS_IS_OK(status)) {
825 errno = map_errno_from_nt_status(status);
826 return -1;
829 ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, mapped_name);
830 TALLOC_FREE(mapped_name);
832 return ret;
835 static ssize_t
836 catia_getxattr(vfs_handle_struct *handle, const char *path,
837 const char *name, void *value, size_t size)
839 char *mapped_name = NULL;
840 NTSTATUS status;
841 ssize_t ret;
843 status = catia_string_replace_allocate(handle->conn,
844 name, &mapped_name, TO_UNIX);
845 if (!NT_STATUS_IS_OK(status)) {
846 errno = map_errno_from_nt_status(status);
847 return -1;
851 ret = SMB_VFS_NEXT_GETXATTR(handle, path, mapped_name, value, size);
852 TALLOC_FREE(mapped_name);
854 return ret;
857 static ssize_t
858 catia_lgetxattr(vfs_handle_struct *handle, const char *path,
859 const char *name, void *value, size_t size)
861 char *mapped_name = NULL;
862 NTSTATUS status;
863 ssize_t ret;
865 status = catia_string_replace_allocate(handle->conn,
866 name, &mapped_name, TO_UNIX);
867 if (!NT_STATUS_IS_OK(status)) {
868 errno = map_errno_from_nt_status(status);
869 return -1;
873 ret = SMB_VFS_NEXT_LGETXATTR(handle, path, mapped_name, value, size);
874 TALLOC_FREE(mapped_name);
876 return ret;
879 static ssize_t
880 catia_listxattr(vfs_handle_struct *handle, const char *path,
881 char *list, size_t size)
883 char *mapped_name = NULL;
884 NTSTATUS status;
885 ssize_t ret;
887 status = catia_string_replace_allocate(handle->conn,
888 path, &mapped_name, TO_UNIX);
889 if (!NT_STATUS_IS_OK(status)) {
890 errno = map_errno_from_nt_status(status);
891 return -1;
895 ret = SMB_VFS_NEXT_LISTXATTR(handle, mapped_name, list, size);
896 TALLOC_FREE(mapped_name);
898 return ret;
901 static ssize_t
902 catia_llistxattr(vfs_handle_struct *handle, const char *path,
903 char *list, size_t size)
905 char *mapped_name = NULL;
906 NTSTATUS status;
907 ssize_t ret;
909 status = catia_string_replace_allocate(handle->conn,
910 path, &mapped_name, TO_UNIX);
911 if (!NT_STATUS_IS_OK(status)) {
912 errno = map_errno_from_nt_status(status);
913 return -1;
917 ret = SMB_VFS_NEXT_LLISTXATTR(handle, mapped_name, list, size);
918 TALLOC_FREE(mapped_name);
920 return ret;
923 static int
924 catia_removexattr(vfs_handle_struct *handle, const char *path,
925 const char *name)
927 char *mapped_name = NULL;
928 NTSTATUS status;
929 ssize_t ret;
931 status = catia_string_replace_allocate(handle->conn,
932 name, &mapped_name, TO_UNIX);
933 if (!NT_STATUS_IS_OK(status)) {
934 errno = map_errno_from_nt_status(status);
935 return -1;
939 ret = SMB_VFS_NEXT_REMOVEXATTR(handle, path, mapped_name);
940 TALLOC_FREE(mapped_name);
942 return ret;
945 static int
946 catia_lremovexattr(vfs_handle_struct *handle, const char *path,
947 const char *name)
949 char *mapped_name = NULL;
950 NTSTATUS status;
951 ssize_t ret;
953 status = catia_string_replace_allocate(handle->conn,
954 name, &mapped_name, TO_UNIX);
955 if (!NT_STATUS_IS_OK(status)) {
956 errno = map_errno_from_nt_status(status);
957 return -1;
961 ret = SMB_VFS_NEXT_LREMOVEXATTR(handle, path, mapped_name);
962 TALLOC_FREE(mapped_name);
964 return ret;
967 static int
968 catia_setxattr(vfs_handle_struct *handle, const char *path,
969 const char *name, const void *value, size_t size,
970 int flags)
972 char *mapped_name = NULL;
973 NTSTATUS status;
974 ssize_t ret;
976 status = catia_string_replace_allocate(handle->conn,
977 name, &mapped_name, TO_UNIX);
978 if (!NT_STATUS_IS_OK(status)) {
979 errno = map_errno_from_nt_status(status);
980 return -1;
984 ret = SMB_VFS_NEXT_SETXATTR(handle, path, mapped_name, value, size, flags);
985 TALLOC_FREE(mapped_name);
987 return ret;
990 static int
991 catia_lsetxattr(vfs_handle_struct *handle, const char *path,
992 const char *name, const void *value, size_t size,
993 int flags)
995 char *mapped_name = NULL;
996 NTSTATUS status;
997 ssize_t ret;
999 status = catia_string_replace_allocate(handle->conn,
1000 name, &mapped_name, TO_UNIX);
1001 if (!NT_STATUS_IS_OK(status)) {
1002 errno = map_errno_from_nt_status(status);
1003 return -1;
1007 ret = SMB_VFS_NEXT_LSETXATTR(handle, path, mapped_name, value, size, flags);
1008 TALLOC_FREE(mapped_name);
1010 return ret;
1013 static struct vfs_fn_pointers vfs_catia_fns = {
1014 .mkdir = catia_mkdir,
1015 .rmdir = catia_rmdir,
1016 .opendir = catia_opendir,
1017 .open = catia_open,
1018 .create_file = catia_createfile,
1019 .rename = catia_rename,
1020 .stat = catia_stat,
1021 .lstat = catia_lstat,
1022 .unlink = catia_unlink,
1023 .chown = catia_chown,
1024 .lchown = catia_lchown,
1025 .chdir = catia_chdir,
1026 .ntimes = catia_ntimes,
1027 .realpath = catia_realpath,
1028 .chflags = catia_chflags,
1029 .streaminfo = catia_streaminfo,
1030 .translate_name = catia_translate_name,
1031 .get_nt_acl = catia_get_nt_acl,
1032 .chmod_acl = catia_chmod_acl,
1033 .sys_acl_get_file = catia_sys_acl_get_file,
1034 .sys_acl_set_file = catia_sys_acl_set_file,
1035 .sys_acl_delete_def_file = catia_sys_acl_delete_def_file,
1036 .getxattr = catia_getxattr,
1037 .lgetxattr = catia_lgetxattr,
1038 .listxattr = catia_listxattr,
1039 .llistxattr = catia_llistxattr,
1040 .removexattr = catia_removexattr,
1041 .lremovexattr = catia_lremovexattr,
1042 .setxattr = catia_setxattr,
1043 .lsetxattr = catia_lsetxattr,
1046 NTSTATUS vfs_catia_init(void)
1048 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "catia",
1049 &vfs_catia_fns);