LCOV - code coverage report
Current view: top level - source3/modules - vfs_catia.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 510 779 65.5 %
Date: 2021-09-23 10:06:22 Functions: 48 62 77.4 %

          Line data    Source code
       1             : /*
       2             :  * Catia VFS module
       3             :  *
       4             :  * Implement a fixed mapping of forbidden NT characters in filenames that are
       5             :  * used a lot by the CAD package Catia.
       6             :  *
       7             :  * Catia V4 on AIX uses characters like "<*$ a *lot*, all forbidden under
       8             :  * Windows...
       9             :  *
      10             :  * Copyright (C) Volker Lendecke, 2005
      11             :  * Copyright (C) Aravind Srinivasan, 2009
      12             :  * Copyright (C) Guenter Kukkukk, 2013
      13             :  * Copyright (C) Ralph Boehme, 2017
      14             :  *
      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.
      19             :  *
      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.
      24             :  *
      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/>.
      27             :  */
      28             : 
      29             : 
      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"
      35             : 
      36             : static int vfs_catia_debug_level = DBGC_VFS;
      37             : 
      38             : #undef DBGC_CLASS
      39             : #define DBGC_CLASS vfs_catia_debug_level
      40             : 
      41             : struct share_mapping_entry {
      42             :         int snum;
      43             :         struct share_mapping_entry *next;
      44             :         struct char_mappings **mappings;
      45             : };
      46             : 
      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;
      54             : };
      55             : 
      56             : static struct share_mapping_entry *srt_head = NULL;
      57             : 
      58      424088 : static struct share_mapping_entry *get_srt(connection_struct *conn,
      59             :                                            struct share_mapping_entry **global)
      60             : {
      61             :         struct share_mapping_entry *share;
      62             : 
      63      424100 :         for (share = srt_head; share != NULL; share = share->next) {
      64      424006 :                 if (share->snum == GLOBAL_SECTION_SNUM)
      65          48 :                         (*global) = share;
      66             : 
      67      424006 :                 if (share->snum == SNUM(conn))
      68      423994 :                         return share;
      69             :         }
      70             : 
      71          94 :         return share;
      72             : }
      73             : 
      74         182 : static struct share_mapping_entry *add_srt(int snum, const char **mappings)
      75             : {
      76         182 :         struct share_mapping_entry *sme = NULL;
      77             : 
      78         182 :         sme = talloc_zero(NULL, struct share_mapping_entry);
      79         182 :         if (sme == NULL)
      80           0 :                 return sme;
      81             : 
      82         182 :         sme->snum = snum;
      83         182 :         sme->next = srt_head;
      84         182 :         srt_head = sme;
      85             : 
      86         182 :         if (mappings == NULL) {
      87          84 :                 sme->mappings = NULL;
      88          84 :                 return sme;
      89             :         }
      90             : 
      91          98 :         sme->mappings = string_replace_init_map(sme, mappings);
      92             : 
      93          98 :         return sme;
      94             : }
      95             : 
      96      424088 : static bool init_mappings(connection_struct *conn,
      97             :                           struct share_mapping_entry **selected_out)
      98             : {
      99      424088 :         const char **mappings = NULL;
     100      424088 :         struct share_mapping_entry *share_level = NULL;
     101      424088 :         struct share_mapping_entry *global = NULL;
     102             : 
     103             :         /* check srt cache */
     104      424088 :         share_level = get_srt(conn, &global);
     105      424088 :         if (share_level) {
     106      423994 :                 *selected_out = share_level;
     107      423994 :                 return (share_level->mappings != NULL);
     108             :         }
     109             : 
     110             :         /* see if we have a global setting */
     111          94 :         if (!global) {
     112             :                 /* global setting */
     113          88 :                 mappings = lp_parm_string_list(-1, "catia", "mappings", NULL);
     114          88 :                 global = add_srt(GLOBAL_SECTION_SNUM, mappings);
     115             :         }
     116             : 
     117             :         /* no global setting - what about share level ? */
     118          94 :         mappings = lp_parm_string_list(SNUM(conn), "catia", "mappings", NULL);
     119          94 :         share_level = add_srt(SNUM(conn), mappings);
     120             : 
     121          94 :         if (share_level->mappings) {
     122          94 :                 (*selected_out) = share_level;
     123          94 :                 return True;
     124             :         }
     125           0 :         if (global->mappings) {
     126           0 :                 share_level->mappings = global->mappings;
     127           0 :                 (*selected_out) = share_level;
     128           0 :                 return True;
     129             :         }
     130             : 
     131           0 :         return False;
     132             : }
     133             : 
     134      424088 : static NTSTATUS catia_string_replace_allocate(connection_struct *conn,
     135             :                                               const char *name_in,
     136             :                                               char **mapped_name,
     137             :                                         enum vfs_translate_direction direction)
     138             : {
     139             :         struct share_mapping_entry *selected;
     140             :         NTSTATUS status;
     141             : 
     142      424088 :         if (!init_mappings(conn, &selected)) {
     143             :                 /* No mappings found. Just use the old name */
     144           0 :                 *mapped_name = talloc_strdup(talloc_tos(), name_in);
     145           0 :                 if (!*mapped_name) {
     146           0 :                         errno = ENOMEM;
     147           0 :                         return NT_STATUS_NO_MEMORY;
     148             :                 }
     149           0 :                 return NT_STATUS_OK;
     150             :         }
     151             : 
     152      848176 :         status = string_replace_allocate(conn,
     153             :                                          name_in,
     154      424088 :                                          selected->mappings,
     155             :                                          talloc_tos(),
     156             :                                          mapped_name,
     157             :                                          direction);
     158      424088 :         return status;
     159             : }
     160             : 
     161          98 : static int catia_connect(struct vfs_handle_struct *handle,
     162             :                          const char *service,
     163             :                          const char *user)
     164             : {
     165             :         /*
     166             :          * Unless we have an async implementation of get_dos_attributes turn
     167             :          * this off.
     168             :          */
     169          98 :         lp_do_parameter(SNUM(handle->conn), "smbd async dosmode", "false");
     170             : 
     171          98 :         return SMB_VFS_NEXT_CONNECT(handle, service, user);
     172             : }
     173             : 
     174             : /*
     175             :  * TRANSLATE_NAME call which converts the given name to
     176             :  * "WINDOWS displayable" name
     177             :  */
     178       15554 : static NTSTATUS catia_translate_name(struct vfs_handle_struct *handle,
     179             :                                      const char *orig_name,
     180             :                                      enum vfs_translate_direction direction,
     181             :                                      TALLOC_CTX *mem_ctx,
     182             :                                      char **pmapped_name)
     183             : {
     184       15554 :         char *name = NULL;
     185             :         char *mapped_name;
     186             :         NTSTATUS status, ret;
     187             : 
     188             :         /*
     189             :          * Copy the supplied name and free the memory for mapped_name,
     190             :          * already allocated by the caller.
     191             :          * We will be allocating new memory for mapped_name in
     192             :          * catia_string_replace_allocate
     193             :          */
     194       15554 :         name = talloc_strdup(talloc_tos(), orig_name);
     195       15554 :         if (!name) {
     196           0 :                 errno = ENOMEM;
     197           0 :                 return NT_STATUS_NO_MEMORY;
     198             :         }
     199       15554 :         status = catia_string_replace_allocate(handle->conn, name,
     200             :                         &mapped_name, direction);
     201             : 
     202       15554 :         TALLOC_FREE(name);
     203       15554 :         if (!NT_STATUS_IS_OK(status)) {
     204           0 :                 return status;
     205             :         }
     206             : 
     207       15554 :         ret = SMB_VFS_NEXT_TRANSLATE_NAME(handle, mapped_name, direction,
     208             :                                           mem_ctx, pmapped_name);
     209             : 
     210       15554 :         if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
     211       15554 :                 *pmapped_name = talloc_move(mem_ctx, &mapped_name);
     212             :                 /* we need to return the former translation result here */
     213       15554 :                 ret = status;
     214             :         } else {
     215           0 :                 TALLOC_FREE(mapped_name);
     216             :         }
     217             : 
     218       15554 :         return ret;
     219             : }
     220             : 
     221             : #define CATIA_DEBUG_CC(lvl, cc, fsp) \
     222             :         catia_debug_cc((lvl), (cc), (fsp), __location__);
     223             : 
     224      285725 : static void catia_debug_cc(int lvl,
     225             :                            struct catia_cache *cc,
     226             :                            files_struct *fsp,
     227             :                            const char *location)
     228             : {
     229      285725 :         DEBUG(lvl, ("%s: cc [%p] cc->busy [%p] "
     230             :                     "is_fsp_ext [%s] "
     231             :                     "fsp [%p] fsp name [%s] "
     232             :                     "orig_fname [%s] "
     233             :                     "fname [%s] "
     234             :                     "orig_base_fname [%s] "
     235             :                     "base_fname [%s]\n",
     236             :                     location,
     237             :                     cc, cc->busy,
     238             :                     cc->is_fsp_ext ? "yes" : "no",
     239             :                     fsp, fsp_str_dbg(fsp),
     240             :                     cc->orig_fname, cc->fname,
     241             :                     cc->orig_base_fname, cc->base_fname));
     242      285725 : }
     243             : 
     244        6795 : static void catia_free_cc(struct catia_cache **_cc,
     245             :                           vfs_handle_struct *handle,
     246             :                           files_struct *fsp)
     247             : {
     248        6795 :         struct catia_cache *cc = *_cc;
     249             : 
     250        6795 :         if (cc->is_fsp_ext) {
     251        6795 :                 VFS_REMOVE_FSP_EXTENSION(handle, fsp);
     252        6795 :                 cc = NULL;
     253             :         } else {
     254           0 :                 TALLOC_FREE(cc);
     255             :         }
     256             : 
     257        6795 :         *_cc = NULL;
     258        6795 : }
     259             : 
     260      144088 : static struct catia_cache *catia_validate_and_apply_cc(
     261             :                                        vfs_handle_struct *handle,
     262             :                                        files_struct *fsp,
     263             :                                        const struct catia_cache * const *busy,
     264             :                                        bool *make_tmp_cache)
     265             : {
     266      144088 :         struct catia_cache *cc = NULL;
     267             : 
     268      144088 :         *make_tmp_cache = false;
     269             : 
     270      144088 :         cc = (struct catia_cache *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
     271      144088 :         if (cc == NULL) {
     272       56634 :                 return NULL;
     273             :         }
     274             : 
     275       87454 :         if (cc->busy != NULL) {
     276        9246 :                 if (cc->busy == busy) {
     277             :                         /* This should never happen */
     278           0 :                         CATIA_DEBUG_CC(0, cc, fsp);
     279           0 :                         smb_panic(__location__);
     280             :                 }
     281             : 
     282             :                 /*
     283             :                  * Recursion. Validate names, the names in the fsp's should be
     284             :                  * the translated names we had set.
     285             :                  */
     286             : 
     287        9246 :                 if ((cc->fname != fsp->fsp_name->base_name)
     288        9246 :                     ||
     289       10894 :                     ((fsp->base_fsp != NULL) &&
     290        1648 :                      (cc->base_fname != fsp->base_fsp->fsp_name->base_name)))
     291             :                 {
     292           0 :                         CATIA_DEBUG_CC(10, cc, fsp);
     293             : 
     294             :                         /*
     295             :                          * Names changed. Setting don't expose the cache on the
     296             :                          * fsp and ask the caller to create a temporary cache.
     297             :                          */
     298           0 :                         *make_tmp_cache = true;
     299           0 :                         return NULL;
     300             :                 }
     301             : 
     302             :                 /*
     303             :                  * Ok, a validated cache while in a recursion, just let the
     304             :                  * caller detect that cc->busy is != busy and there's
     305             :                  * nothing else to do.
     306             :                  */
     307        9246 :                 CATIA_DEBUG_CC(10, cc, fsp);
     308        9246 :                 return cc;
     309             :         }
     310             : 
     311             :         /* Not in a recursion */
     312             : 
     313       78208 :         if ((cc->orig_fname != fsp->fsp_name->base_name)
     314       71413 :             ||
     315       77102 :             ((fsp->base_fsp != NULL) &&
     316        5689 :              (cc->orig_base_fname != fsp->base_fsp->fsp_name->base_name)))
     317             :         {
     318             :                 /*
     319             :                  * fsp names changed, this can happen in an rename op.
     320             :                  * Trigger recreation as a full fledged fsp extension.
     321             :                  */
     322             : 
     323        6795 :                 CATIA_DEBUG_CC(10, cc, fsp);
     324        6795 :                 catia_free_cc(&cc, handle, fsp);
     325        6795 :                 return NULL;
     326             :         }
     327             : 
     328             : 
     329             :         /*
     330             :          * Ok, we found a valid cache entry, no recursion. Just set translated
     331             :          * names from the cache and mark the cc as busy.
     332             :          */
     333       71413 :         fsp->fsp_name->base_name = cc->fname;
     334       71413 :         if (fsp->base_fsp != NULL) {
     335        5689 :                 fsp->base_fsp->fsp_name->base_name = cc->base_fname;
     336             :         }
     337             : 
     338       71413 :         cc->busy = busy;
     339       71413 :         CATIA_DEBUG_CC(10, cc, fsp);
     340       71413 :         return cc;
     341             : }
     342             : 
     343             : #define CATIA_FETCH_FSP_PRE_NEXT(mem_ctx, handle, fsp, _cc) \
     344             :         catia_fetch_fsp_pre_next((mem_ctx), (handle), (fsp), (_cc), __func__);
     345             : 
     346      144088 : static int catia_fetch_fsp_pre_next(TALLOC_CTX *mem_ctx,
     347             :                                     vfs_handle_struct *handle,
     348             :                                     files_struct *fsp,
     349             :                                     struct catia_cache **_cc,
     350             :                                     const char *function)
     351             : {
     352      144088 :         const struct catia_cache * const *busy =
     353             :                 (const struct catia_cache * const *)_cc;
     354      144088 :         struct catia_cache *cc = NULL;
     355             :         NTSTATUS status;
     356      144088 :         bool make_tmp_cache = false;
     357             : 
     358      144088 :         *_cc = NULL;
     359             : 
     360      144088 :         DBG_DEBUG("Called from [%s]\n", function);
     361             : 
     362      144088 :         cc = catia_validate_and_apply_cc(handle,
     363             :                                          fsp,
     364             :                                          busy,
     365             :                                          &make_tmp_cache);
     366      144088 :         if (cc != NULL) {
     367       80659 :                 if (cc->busy != busy) {
     368        9246 :                         return 0;
     369             :                 }
     370       71413 :                 *_cc = cc;
     371       71413 :                 return 0;
     372             :         }
     373             : 
     374       63429 :         if (!make_tmp_cache) {
     375       63429 :                 cc = VFS_ADD_FSP_EXTENSION(
     376             :                         handle, fsp, struct catia_cache, NULL);
     377       63429 :                 if (cc == NULL) {
     378           0 :                         return -1;
     379             :                 }
     380       63429 :                 *cc = (struct catia_cache) {
     381             :                         .is_fsp_ext = true,
     382             :                 };
     383             : 
     384       63429 :                 mem_ctx = VFS_MEMCTX_FSP_EXTENSION(handle, fsp);
     385       63429 :                 if (mem_ctx == NULL) {
     386           0 :                         DBG_ERR("VFS_MEMCTX_FSP_EXTENSION failed\n");
     387           0 :                         catia_free_cc(&cc, handle, fsp);
     388           0 :                         return -1;
     389             :                 }
     390             :         } else {
     391           0 :                 cc = talloc_zero(mem_ctx, struct catia_cache);
     392           0 :                 if (cc == NULL) {
     393           0 :                         return -1;
     394             :                 }
     395           0 :                 mem_ctx = cc;
     396             :         }
     397             : 
     398             : 
     399      126858 :         status = catia_string_replace_allocate(handle->conn,
     400       63429 :                                                fsp->fsp_name->base_name,
     401       63429 :                                                &cc->fname,
     402             :                                                vfs_translate_to_unix);
     403       63429 :         if (!NT_STATUS_IS_OK(status)) {
     404           0 :                 catia_free_cc(&cc, handle, fsp);
     405           0 :                 errno = map_errno_from_nt_status(status);
     406           0 :                 return -1;
     407             :         }
     408       63429 :         talloc_steal(mem_ctx, cc->fname);
     409             : 
     410       63429 :         if (fsp->base_fsp != NULL) {
     411        5214 :                 status = catia_string_replace_allocate(
     412        2607 :                         handle->conn,
     413        2607 :                         fsp->base_fsp->fsp_name->base_name,
     414        2607 :                         &cc->base_fname,
     415             :                         vfs_translate_to_unix);
     416        2607 :                 if (!NT_STATUS_IS_OK(status)) {
     417           0 :                         catia_free_cc(&cc, handle, fsp);
     418           0 :                         errno = map_errno_from_nt_status(status);
     419           0 :                         return -1;
     420             :                 }
     421        2607 :                 talloc_steal(mem_ctx, cc->base_fname);
     422             :         }
     423             : 
     424       63429 :         cc->orig_fname = fsp->fsp_name->base_name;
     425       63429 :         fsp->fsp_name->base_name = cc->fname;
     426             : 
     427       63429 :         if (fsp->base_fsp != NULL) {
     428        2607 :                 cc->orig_base_fname = fsp->base_fsp->fsp_name->base_name;
     429        2607 :                 fsp->base_fsp->fsp_name->base_name = cc->base_fname;
     430             :         }
     431             : 
     432       63429 :         cc->busy = busy;
     433       63429 :         CATIA_DEBUG_CC(10, cc, fsp);
     434             : 
     435       63429 :         *_cc = cc;
     436             : 
     437       63429 :         return 0;
     438             : }
     439             : 
     440             : #define CATIA_FETCH_FSP_POST_NEXT(_cc, fsp) do { \
     441             :         int catia_saved_errno = errno; \
     442             :         catia_fetch_fsp_post_next((_cc), (fsp), __func__); \
     443             :         errno = catia_saved_errno; \
     444             : } while(0)
     445             : 
     446      144088 : static void catia_fetch_fsp_post_next(struct catia_cache **_cc,
     447             :                                       files_struct *fsp,
     448             :                                       const char *function)
     449             : {
     450      144088 :         const struct catia_cache * const *busy =
     451             :                 (const struct catia_cache * const *)_cc;
     452      144088 :         struct catia_cache *cc = *_cc;
     453             : 
     454      144088 :         DBG_DEBUG("Called from [%s]\n", function);
     455             : 
     456      144088 :         if (cc == NULL) {
     457             :                 /*
     458             :                  * This can happen when recursing in the VFS on the fsp when the
     459             :                  * pre_next func noticed the recursion and set out cc pointer to
     460             :                  * NULL.
     461             :                  */
     462        9246 :                 return;
     463             :         }
     464             : 
     465      134842 :         if (cc->busy != busy) {
     466           0 :                 CATIA_DEBUG_CC(0, cc, fsp);
     467           0 :                 smb_panic(__location__);
     468             :                 return;
     469             :         }
     470             : 
     471      134842 :         cc->busy = NULL;
     472      134842 :         *_cc = NULL;
     473             : 
     474      134842 :         fsp->fsp_name->base_name = cc->orig_fname;
     475      134842 :         if (fsp->base_fsp != NULL) {
     476        8296 :                 fsp->base_fsp->fsp_name->base_name = cc->orig_base_fname;
     477             :         }
     478             : 
     479      134842 :         CATIA_DEBUG_CC(10, cc, fsp);
     480             : 
     481      134842 :         if (!cc->is_fsp_ext) {
     482           0 :                 TALLOC_FREE(cc);
     483             :         }
     484             : 
     485      134842 :         return;
     486             : }
     487             : 
     488       57426 : static int catia_openat(vfs_handle_struct *handle,
     489             :                         const struct files_struct *dirfsp,
     490             :                         const struct smb_filename *smb_fname_in,
     491             :                         files_struct *fsp,
     492             :                         int flags,
     493             :                         mode_t mode)
     494             : {
     495       57426 :         struct smb_filename *smb_fname = NULL;
     496       57426 :         struct catia_cache *cc = NULL;
     497       57426 :         char *mapped_name = NULL;
     498             :         NTSTATUS status;
     499             :         int ret;
     500       57426 :         int saved_errno = 0;
     501             : 
     502       57426 :         status = catia_string_replace_allocate(handle->conn,
     503       57426 :                                                smb_fname_in->base_name,
     504             :                                                &mapped_name,
     505             :                                                vfs_translate_to_unix);
     506       57426 :         if (!NT_STATUS_IS_OK(status)) {
     507           0 :                 return -1;
     508             :         }
     509             : 
     510       57426 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
     511       57426 :         if (ret != 0) {
     512           0 :                 TALLOC_FREE(mapped_name);
     513           0 :                 return ret;
     514             :         }
     515             : 
     516       57426 :         smb_fname = cp_smb_filename(talloc_tos(), smb_fname_in);
     517       57426 :         if (smb_fname == NULL) {
     518           0 :                 TALLOC_FREE(mapped_name);
     519           0 :                 errno = ENOMEM;
     520           0 :                 return -1;
     521             :         }
     522       57426 :         smb_fname->base_name = mapped_name;
     523             : 
     524       57426 :         ret = SMB_VFS_NEXT_OPENAT(handle,
     525             :                                   dirfsp,
     526             :                                   smb_fname,
     527             :                                   fsp,
     528             :                                   flags,
     529             :                                   mode);
     530             : 
     531       57426 :         if (ret == -1) {
     532        2106 :                 saved_errno = errno;
     533             :         }
     534       57426 :         TALLOC_FREE(smb_fname);
     535       57426 :         TALLOC_FREE(mapped_name);
     536       57426 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
     537       57426 :         if (saved_errno != 0) {
     538        2106 :                 errno = saved_errno;
     539             :         }
     540       57426 :         return ret;
     541             : }
     542             : 
     543           2 : static int catia_renameat(vfs_handle_struct *handle,
     544             :                         files_struct *srcfsp,
     545             :                         const struct smb_filename *smb_fname_src,
     546             :                         files_struct *dstfsp,
     547             :                         const struct smb_filename *smb_fname_dst)
     548             : {
     549           2 :         TALLOC_CTX *ctx = talloc_tos();
     550           2 :         struct smb_filename *smb_fname_src_tmp = NULL;
     551           2 :         struct smb_filename *smb_fname_dst_tmp = NULL;
     552           2 :         char *src_name_mapped = NULL;
     553           2 :         char *dst_name_mapped = NULL;
     554             :         NTSTATUS status;
     555           2 :         int ret = -1;
     556             : 
     557           2 :         status = catia_string_replace_allocate(handle->conn,
     558           2 :                                 smb_fname_src->base_name,
     559             :                                 &src_name_mapped, vfs_translate_to_unix);
     560           2 :         if (!NT_STATUS_IS_OK(status)) {
     561           0 :                 errno = map_errno_from_nt_status(status);
     562           0 :                 return -1;
     563             :         }
     564             : 
     565           2 :         status = catia_string_replace_allocate(handle->conn,
     566           2 :                                 smb_fname_dst->base_name,
     567             :                                 &dst_name_mapped, vfs_translate_to_unix);
     568           2 :         if (!NT_STATUS_IS_OK(status)) {
     569           0 :                 errno = map_errno_from_nt_status(status);
     570           0 :                 return -1;
     571             :         }
     572             : 
     573             :         /* Setup temporary smb_filename structs. */
     574           2 :         smb_fname_src_tmp = cp_smb_filename(ctx, smb_fname_src);
     575           2 :         if (smb_fname_src_tmp == NULL) {
     576           0 :                 errno = ENOMEM;
     577           0 :                 goto out;
     578             :         }
     579             : 
     580           2 :         smb_fname_dst_tmp = cp_smb_filename(ctx, smb_fname_dst);
     581           2 :         if (smb_fname_dst_tmp == NULL) {
     582           0 :                 errno = ENOMEM;
     583           0 :                 goto out;
     584             :         }
     585             : 
     586           2 :         smb_fname_src_tmp->base_name = src_name_mapped;
     587           2 :         smb_fname_dst_tmp->base_name = dst_name_mapped;
     588           2 :         DEBUG(10, ("converted old name: %s\n",
     589             :                                 smb_fname_str_dbg(smb_fname_src_tmp)));
     590           2 :         DEBUG(10, ("converted new name: %s\n",
     591             :                                 smb_fname_str_dbg(smb_fname_dst_tmp)));
     592             : 
     593           2 :         ret = SMB_VFS_NEXT_RENAMEAT(handle,
     594             :                         srcfsp,
     595             :                         smb_fname_src_tmp,
     596             :                         dstfsp,
     597             :                         smb_fname_dst_tmp);
     598             : 
     599           2 : out:
     600           2 :         TALLOC_FREE(src_name_mapped);
     601           2 :         TALLOC_FREE(dst_name_mapped);
     602           2 :         TALLOC_FREE(smb_fname_src_tmp);
     603           2 :         TALLOC_FREE(smb_fname_dst_tmp);
     604           2 :         return ret;
     605             : }
     606             : 
     607             : 
     608      128734 : static int catia_stat(vfs_handle_struct *handle,
     609             :                       struct smb_filename *smb_fname)
     610             : {
     611      128734 :         char *name = NULL;
     612             :         char *tmp_base_name;
     613             :         int ret;
     614             :         NTSTATUS status;
     615             : 
     616      128734 :         status = catia_string_replace_allocate(handle->conn,
     617      128734 :                                 smb_fname->base_name,
     618             :                                 &name, vfs_translate_to_unix);
     619      128734 :         if (!NT_STATUS_IS_OK(status)) {
     620           0 :                 errno = map_errno_from_nt_status(status);
     621           0 :                 return -1;
     622             :         }
     623             : 
     624      128734 :         tmp_base_name = smb_fname->base_name;
     625      128734 :         smb_fname->base_name = name;
     626             : 
     627      128734 :         ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
     628      128734 :         smb_fname->base_name = tmp_base_name;
     629             : 
     630      128734 :         TALLOC_FREE(name);
     631      128734 :         return ret;
     632             : }
     633             : 
     634         116 : static int catia_lstat(vfs_handle_struct *handle,
     635             :                        struct smb_filename *smb_fname)
     636             : {
     637         116 :         char *name = NULL;
     638             :         char *tmp_base_name;
     639             :         int ret;
     640             :         NTSTATUS status;
     641             : 
     642         116 :         status = catia_string_replace_allocate(handle->conn,
     643         116 :                                 smb_fname->base_name,
     644             :                                 &name, vfs_translate_to_unix);
     645         116 :         if (!NT_STATUS_IS_OK(status)) {
     646           0 :                 errno = map_errno_from_nt_status(status);
     647           0 :                 return -1;
     648             :         }
     649             : 
     650         116 :         tmp_base_name = smb_fname->base_name;
     651         116 :         smb_fname->base_name = name;
     652             : 
     653         116 :         ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
     654         116 :         smb_fname->base_name = tmp_base_name;
     655         116 :         TALLOC_FREE(name);
     656             : 
     657         116 :         return ret;
     658             : }
     659             : 
     660         370 : static int catia_unlinkat(vfs_handle_struct *handle,
     661             :                         struct files_struct *dirfsp,
     662             :                         const struct smb_filename *smb_fname,
     663             :                         int flags)
     664             : {
     665         370 :         struct catia_cache *cc = NULL;
     666         370 :         struct smb_filename *smb_fname_tmp = NULL;
     667         370 :         char *name = NULL;
     668             :         NTSTATUS status;
     669             :         int ret;
     670             : 
     671         370 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, dirfsp, &cc);
     672         370 :         if (ret != 0) {
     673           0 :                 return ret;
     674             :         }
     675             : 
     676         370 :         status = catia_string_replace_allocate(handle->conn,
     677         370 :                                         smb_fname->base_name,
     678             :                                         &name, vfs_translate_to_unix);
     679         370 :         if (!NT_STATUS_IS_OK(status)) {
     680           0 :                 errno = map_errno_from_nt_status(status);
     681           0 :                 goto out;
     682             :         }
     683             : 
     684             :         /* Setup temporary smb_filename structs. */
     685         370 :         smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
     686         370 :         if (smb_fname_tmp == NULL) {
     687           0 :                 errno = ENOMEM;
     688           0 :                 goto out;
     689             :         }
     690             : 
     691         370 :         smb_fname_tmp->base_name = name;
     692         370 :         smb_fname_tmp->fsp = smb_fname->fsp;
     693             : 
     694         370 :         ret = SMB_VFS_NEXT_UNLINKAT(handle,
     695             :                         dirfsp,
     696             :                         smb_fname_tmp,
     697             :                         flags);
     698         370 :         TALLOC_FREE(smb_fname_tmp);
     699         740 :         TALLOC_FREE(name);
     700             : 
     701         370 : out:
     702         370 :         CATIA_FETCH_FSP_POST_NEXT(&cc, dirfsp);
     703         370 :         return ret;
     704             : }
     705             : 
     706           0 : static int catia_lchown(vfs_handle_struct *handle,
     707             :                         const struct smb_filename *smb_fname,
     708             :                         uid_t uid,
     709             :                         gid_t gid)
     710             : {
     711           0 :         char *name = NULL;
     712             :         NTSTATUS status;
     713             :         int ret;
     714             :         int saved_errno;
     715           0 :         struct smb_filename *catia_smb_fname = NULL;
     716             : 
     717           0 :         status = catia_string_replace_allocate(handle->conn,
     718           0 :                                         smb_fname->base_name,
     719             :                                         &name,
     720             :                                         vfs_translate_to_unix);
     721           0 :         if (!NT_STATUS_IS_OK(status)) {
     722           0 :                 errno = map_errno_from_nt_status(status);
     723           0 :                 return -1;
     724             :         }
     725           0 :         catia_smb_fname = synthetic_smb_fname(talloc_tos(),
     726             :                                         name,
     727             :                                         NULL,
     728             :                                         &smb_fname->st,
     729             :                                         smb_fname->twrp,
     730             :                                         smb_fname->flags);
     731           0 :         if (catia_smb_fname == NULL) {
     732           0 :                 TALLOC_FREE(name);
     733           0 :                 errno = ENOMEM;
     734           0 :                 return -1;
     735             :         }
     736             : 
     737           0 :         ret = SMB_VFS_NEXT_LCHOWN(handle, catia_smb_fname, uid, gid);
     738           0 :         saved_errno = errno;
     739           0 :         TALLOC_FREE(name);
     740           0 :         TALLOC_FREE(catia_smb_fname);
     741           0 :         errno = saved_errno;
     742           0 :         return ret;
     743             : }
     744             : 
     745          62 : static int catia_mkdirat(vfs_handle_struct *handle,
     746             :                         struct files_struct *dirfsp,
     747             :                         const struct smb_filename *smb_fname,
     748             :                         mode_t mode)
     749             : {
     750          62 :         char *name = NULL;
     751             :         NTSTATUS status;
     752             :         int ret;
     753          62 :         struct smb_filename *catia_smb_fname = NULL;
     754             : 
     755          62 :         status = catia_string_replace_allocate(handle->conn,
     756          62 :                                 smb_fname->base_name,
     757             :                                 &name,
     758             :                                 vfs_translate_to_unix);
     759          62 :         if (!NT_STATUS_IS_OK(status)) {
     760           0 :                 errno = map_errno_from_nt_status(status);
     761           0 :                 return -1;
     762             :         }
     763          62 :         catia_smb_fname = synthetic_smb_fname(talloc_tos(),
     764             :                                         name,
     765             :                                         NULL,
     766             :                                         &smb_fname->st,
     767             :                                         smb_fname->twrp,
     768             :                                         smb_fname->flags);
     769          62 :         if (catia_smb_fname == NULL) {
     770           0 :                 TALLOC_FREE(name);
     771           0 :                 errno = ENOMEM;
     772           0 :                 return -1;
     773             :         }
     774             : 
     775          62 :         ret = SMB_VFS_NEXT_MKDIRAT(handle,
     776             :                         dirfsp,
     777             :                         catia_smb_fname,
     778             :                         mode);
     779          62 :         TALLOC_FREE(name);
     780          62 :         TALLOC_FREE(catia_smb_fname);
     781             : 
     782          62 :         return ret;
     783             : }
     784             : 
     785       31980 : static int catia_chdir(vfs_handle_struct *handle,
     786             :                         const struct smb_filename *smb_fname)
     787             : {
     788       31980 :         char *name = NULL;
     789       31980 :         struct smb_filename *catia_smb_fname = NULL;
     790             :         NTSTATUS status;
     791             :         int ret;
     792             : 
     793       31980 :         status = catia_string_replace_allocate(handle->conn,
     794       31980 :                                         smb_fname->base_name,
     795             :                                         &name,
     796             :                                         vfs_translate_to_unix);
     797       31980 :         if (!NT_STATUS_IS_OK(status)) {
     798           0 :                 errno = map_errno_from_nt_status(status);
     799           0 :                 return -1;
     800             :         }
     801             : 
     802       31980 :         catia_smb_fname = synthetic_smb_fname(talloc_tos(),
     803             :                                         name,
     804             :                                         NULL,
     805             :                                         &smb_fname->st,
     806             :                                         smb_fname->twrp,
     807             :                                         smb_fname->flags);
     808       31980 :         if (catia_smb_fname == NULL) {
     809           0 :                 TALLOC_FREE(name);
     810           0 :                 errno = ENOMEM;
     811           0 :                 return -1;
     812             :         }
     813       31980 :         ret = SMB_VFS_NEXT_CHDIR(handle, catia_smb_fname);
     814       31980 :         TALLOC_FREE(name);
     815       31980 :         TALLOC_FREE(catia_smb_fname);
     816             : 
     817       31980 :         return ret;
     818             : }
     819             : 
     820         464 : static int catia_fntimes(vfs_handle_struct *handle,
     821             :                          files_struct *fsp,
     822             :                          struct smb_file_time *ft)
     823             : {
     824         464 :         struct catia_cache *cc = NULL;
     825             :         int ret;
     826             : 
     827         464 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
     828         464 :         if (ret != 0) {
     829           0 :                 return ret;
     830             :         }
     831             : 
     832         464 :         ret = SMB_VFS_NEXT_FNTIMES(handle, fsp, ft);
     833             : 
     834         464 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
     835             : 
     836         464 :         return ret;
     837             : }
     838             : 
     839             : static struct smb_filename *
     840       61658 : catia_realpath(vfs_handle_struct *handle,
     841             :                 TALLOC_CTX *ctx,
     842             :                 const struct smb_filename *smb_fname)
     843             : {
     844       61658 :         char *mapped_name = NULL;
     845       61658 :         struct smb_filename *catia_smb_fname = NULL;
     846       61658 :         struct smb_filename *return_fname = NULL;
     847             :         NTSTATUS status;
     848             : 
     849       61658 :         status = catia_string_replace_allocate(handle->conn,
     850       61658 :                                         smb_fname->base_name,
     851             :                                         &mapped_name, vfs_translate_to_unix);
     852       61658 :         if (!NT_STATUS_IS_OK(status)) {
     853           0 :                 errno = map_errno_from_nt_status(status);
     854           0 :                 return NULL;
     855             :         }
     856             : 
     857       61658 :         catia_smb_fname = synthetic_smb_fname(talloc_tos(),
     858             :                                         mapped_name,
     859             :                                         NULL,
     860             :                                         &smb_fname->st,
     861             :                                         smb_fname->twrp,
     862             :                                         smb_fname->flags);
     863       61658 :         if (catia_smb_fname == NULL) {
     864           0 :                 TALLOC_FREE(mapped_name);
     865           0 :                 errno = ENOMEM;
     866           0 :                 return NULL;
     867             :         }
     868       61658 :         return_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, catia_smb_fname);
     869       61658 :         TALLOC_FREE(mapped_name);
     870       61658 :         TALLOC_FREE(catia_smb_fname);
     871       61658 :         return return_fname;
     872             : }
     873             : 
     874             : static NTSTATUS
     875        1372 : catia_fstreaminfo(struct vfs_handle_struct *handle,
     876             :                  struct files_struct *fsp,
     877             :                  TALLOC_CTX *mem_ctx,
     878             :                  unsigned int *_num_streams,
     879             :                  struct stream_struct **_streams)
     880             : {
     881        1372 :         char *mapped_name = NULL;
     882             :         NTSTATUS status;
     883             :         unsigned int i;
     884        1372 :         struct smb_filename *catia_smb_fname = NULL;
     885        1372 :         struct smb_filename *smb_fname = NULL;
     886        1372 :         unsigned int num_streams = 0;
     887        1372 :         struct stream_struct *streams = NULL;
     888             : 
     889        1372 :         smb_fname = fsp->fsp_name;
     890        1372 :         *_num_streams = 0;
     891        1372 :         *_streams = NULL;
     892             : 
     893        1372 :         status = catia_string_replace_allocate(handle->conn,
     894        1372 :                                 smb_fname->base_name,
     895             :                                 &mapped_name,
     896             :                                 vfs_translate_to_unix);
     897        1372 :         if (!NT_STATUS_IS_OK(status)) {
     898           0 :                 return status;
     899             :         }
     900             : 
     901        4116 :         status = synthetic_pathref(talloc_tos(),
     902        1372 :                                         handle->conn->cwd_fsp,
     903             :                                         mapped_name,
     904             :                                         NULL,
     905        1372 :                                         &smb_fname->st,
     906             :                                         smb_fname->twrp,
     907             :                                         smb_fname->flags,
     908             :                                         &catia_smb_fname);
     909             : 
     910        1372 :         if (!NT_STATUS_IS_OK(status)) {
     911           0 :                 TALLOC_FREE(mapped_name);
     912           0 :                 return status;
     913             :         }
     914             : 
     915        1372 :         status = SMB_VFS_NEXT_FSTREAMINFO(handle,
     916             :                                           catia_smb_fname->fsp,
     917             :                                           mem_ctx,
     918             :                                           &num_streams,
     919             :                                           &streams);
     920        1372 :         TALLOC_FREE(mapped_name);
     921        1372 :         TALLOC_FREE(catia_smb_fname);
     922        1372 :         if (!NT_STATUS_IS_OK(status)) {
     923           0 :                 return status;
     924             :         }
     925             : 
     926             :         /*
     927             :          * Translate stream names just like the base names
     928             :          */
     929        2930 :         for (i = 0; i < num_streams; i++) {
     930             :                 /*
     931             :                  * Strip ":" prefix and ":$DATA" suffix to get a
     932             :                  * "pure" stream name and only translate that.
     933             :                  */
     934        1558 :                 void *old_ptr = streams[i].name;
     935        1558 :                 char *stream_name = streams[i].name + 1;
     936        1558 :                 char *stream_type = strrchr_m(stream_name, ':');
     937             : 
     938        1558 :                 if (stream_type != NULL) {
     939        1558 :                         *stream_type = '\0';
     940        1558 :                         stream_type += 1;
     941             :                 }
     942             : 
     943        1558 :                 status = catia_string_replace_allocate(handle->conn,
     944             :                                                 stream_name,
     945             :                                                 &mapped_name,
     946             :                                                 vfs_translate_to_windows);
     947        1558 :                 if (!NT_STATUS_IS_OK(status)) {
     948           0 :                         TALLOC_FREE(streams);
     949           0 :                         return status;
     950             :                 }
     951             : 
     952        1558 :                 if (stream_type != NULL) {
     953        1558 :                         streams[i].name = talloc_asprintf(streams,
     954             :                                                           ":%s:%s",
     955             :                                                           mapped_name,
     956             :                                                           stream_type);
     957             :                 } else {
     958           0 :                         streams[i].name = talloc_asprintf(streams,
     959             :                                                           ":%s",
     960             :                                                           mapped_name);
     961             :                 }
     962        1558 :                 TALLOC_FREE(mapped_name);
     963        1558 :                 TALLOC_FREE(old_ptr);
     964        1558 :                 if (streams[i].name == NULL) {
     965           0 :                         TALLOC_FREE(streams);
     966           0 :                         return NT_STATUS_NO_MEMORY;
     967             :                 }
     968             :         }
     969             : 
     970        1372 :         *_num_streams = num_streams;
     971        1372 :         *_streams = streams;
     972        1372 :         return NT_STATUS_OK;
     973             : }
     974             : 
     975       61974 : static int catia_fstat(vfs_handle_struct *handle,
     976             :                        files_struct *fsp,
     977             :                        SMB_STRUCT_STAT *sbuf)
     978             : {
     979       61974 :         struct catia_cache *cc = NULL;
     980             :         int ret;
     981             : 
     982       61974 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
     983       61974 :         if (ret != 0) {
     984           0 :                 return ret;
     985             :         }
     986             : 
     987       61974 :         ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
     988             : 
     989       61974 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
     990             : 
     991       61974 :         return ret;
     992             : }
     993             : 
     994         180 : static ssize_t catia_pread(vfs_handle_struct *handle,
     995             :                            files_struct *fsp, void *data,
     996             :                            size_t n, off_t offset)
     997             : {
     998         180 :         struct catia_cache *cc = NULL;
     999             :         ssize_t result;
    1000             :         int ret;
    1001             : 
    1002         180 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1003         180 :         if (ret != 0) {
    1004           0 :                 return ret;
    1005             :         }
    1006             : 
    1007         180 :         result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
    1008             : 
    1009         180 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1010             : 
    1011         180 :         return result;
    1012             : }
    1013             : 
    1014         764 : static ssize_t catia_pwrite(vfs_handle_struct *handle,
    1015             :                             files_struct *fsp, const void *data,
    1016             :                             size_t n, off_t offset)
    1017             : {
    1018         764 :         struct catia_cache *cc = NULL;
    1019             :         ssize_t result;
    1020             :         int ret;
    1021             : 
    1022         764 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1023         764 :         if (ret != 0) {
    1024           0 :                 return ret;
    1025             :         }
    1026             : 
    1027         764 :         result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
    1028             : 
    1029         764 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1030             : 
    1031         764 :         return result;
    1032             : }
    1033             : 
    1034          44 : static int catia_ftruncate(struct vfs_handle_struct *handle,
    1035             :                            struct files_struct *fsp,
    1036             :                            off_t offset)
    1037             : {
    1038          44 :         struct catia_cache *cc = NULL;
    1039             :         int ret;
    1040             : 
    1041          44 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1042          44 :         if (ret != 0) {
    1043           0 :                 return ret;
    1044             :         }
    1045             : 
    1046          44 :         ret = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
    1047             : 
    1048          44 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1049             : 
    1050          44 :         return ret;
    1051             : }
    1052             : 
    1053           0 : static int catia_fallocate(struct vfs_handle_struct *handle,
    1054             :                            struct files_struct *fsp,
    1055             :                            uint32_t mode,
    1056             :                            off_t offset,
    1057             :                            off_t len)
    1058             : {
    1059           0 :         struct catia_cache *cc = NULL;
    1060             :         int ret;
    1061             : 
    1062           0 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1063           0 :         if (ret != 0) {
    1064           0 :                 return ret;
    1065             :         }
    1066             : 
    1067           0 :         ret = SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
    1068             : 
    1069           0 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1070             : 
    1071           0 :         return ret;
    1072             : }
    1073             : 
    1074       58154 : static ssize_t catia_fgetxattr(struct vfs_handle_struct *handle,
    1075             :                                struct files_struct *fsp,
    1076             :                                const char *name,
    1077             :                                void *value,
    1078             :                                size_t size)
    1079             : {
    1080       58154 :         char *mapped_xattr_name = NULL;
    1081             :         NTSTATUS status;
    1082             :         ssize_t result;
    1083             : 
    1084       58154 :         status = catia_string_replace_allocate(handle->conn,
    1085             :                                                name, &mapped_xattr_name,
    1086             :                                                vfs_translate_to_unix);
    1087       58154 :         if (!NT_STATUS_IS_OK(status)) {
    1088           0 :                 errno = map_errno_from_nt_status(status);
    1089           0 :                 return -1;
    1090             :         }
    1091             : 
    1092       58154 :         result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, mapped_xattr_name,
    1093             :                                         value, size);
    1094             : 
    1095       58154 :         TALLOC_FREE(mapped_xattr_name);
    1096             : 
    1097       58154 :         return result;
    1098             : }
    1099             : 
    1100        1424 : static ssize_t catia_flistxattr(struct vfs_handle_struct *handle,
    1101             :                                 struct files_struct *fsp,
    1102             :                                 char *list,
    1103             :                                 size_t size)
    1104             : {
    1105        1424 :         struct catia_cache *cc = NULL;
    1106             :         ssize_t result;
    1107             :         int ret;
    1108             : 
    1109        1424 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1110        1424 :         if (ret != 0) {
    1111           0 :                 return ret;
    1112             :         }
    1113             : 
    1114        1424 :         result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
    1115             : 
    1116        1424 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1117             : 
    1118        1424 :         return result;
    1119             : }
    1120             : 
    1121         150 : static int catia_fremovexattr(struct vfs_handle_struct *handle,
    1122             :                               struct files_struct *fsp,
    1123             :                               const char *name)
    1124             : {
    1125         150 :         char *mapped_name = NULL;
    1126             :         NTSTATUS status;
    1127             :         int ret;
    1128             : 
    1129         150 :         status = catia_string_replace_allocate(handle->conn,
    1130             :                                 name, &mapped_name, vfs_translate_to_unix);
    1131         150 :         if (!NT_STATUS_IS_OK(status)) {
    1132           0 :                 errno = map_errno_from_nt_status(status);
    1133           0 :                 return -1;
    1134             :         }
    1135             : 
    1136         150 :         ret = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, mapped_name);
    1137             : 
    1138         150 :         TALLOC_FREE(mapped_name);
    1139             : 
    1140         150 :         return ret;
    1141             : }
    1142             : 
    1143         914 : static int catia_fsetxattr(struct vfs_handle_struct *handle,
    1144             :                            struct files_struct *fsp,
    1145             :                            const char *name,
    1146             :                            const void *value,
    1147             :                            size_t size,
    1148             :                            int flags)
    1149             : {
    1150         914 :         char *mapped_xattr_name = NULL;
    1151             :         NTSTATUS status;
    1152             :         int ret;
    1153             : 
    1154         914 :         status = catia_string_replace_allocate(
    1155         914 :                 handle->conn, name, &mapped_xattr_name, vfs_translate_to_unix);
    1156         914 :         if (!NT_STATUS_IS_OK(status)) {
    1157           0 :                 errno = map_errno_from_nt_status(status);
    1158           0 :                 return -1;
    1159             :         }
    1160             : 
    1161         914 :         ret = SMB_VFS_NEXT_FSETXATTR(handle, fsp, mapped_xattr_name,
    1162             :                                      value, size, flags);
    1163             : 
    1164         914 :         TALLOC_FREE(mapped_xattr_name);
    1165             : 
    1166         914 :         return ret;
    1167             : }
    1168             : 
    1169        3894 : static SMB_ACL_T catia_sys_acl_get_fd(vfs_handle_struct *handle,
    1170             :                                       files_struct *fsp,
    1171             :                                       SMB_ACL_TYPE_T type,
    1172             :                                       TALLOC_CTX *mem_ctx)
    1173             : {
    1174        3894 :         struct catia_cache *cc = NULL;
    1175        3894 :         struct smb_acl_t *result = NULL;
    1176             :         int ret;
    1177             : 
    1178        3894 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1179        3894 :         if (ret != 0) {
    1180           0 :                 return NULL;
    1181             :         }
    1182             : 
    1183        3894 :         result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, type, mem_ctx);
    1184             : 
    1185        3894 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1186             : 
    1187        3894 :         return result;
    1188             : }
    1189             : 
    1190           0 : static int catia_sys_acl_blob_get_fd(vfs_handle_struct *handle,
    1191             :                                      files_struct *fsp,
    1192             :                                      TALLOC_CTX *mem_ctx,
    1193             :                                      char **blob_description,
    1194             :                                      DATA_BLOB *blob)
    1195             : {
    1196           0 :         struct catia_cache *cc = NULL;
    1197             :         int ret;
    1198             : 
    1199           0 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1200           0 :         if (ret != 0) {
    1201           0 :                 return ret;
    1202             :         }
    1203             : 
    1204           0 :         ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx,
    1205             :                                                blob_description, blob);
    1206             : 
    1207           0 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1208             : 
    1209           0 :         return ret;
    1210             : }
    1211             : 
    1212         248 : static int catia_sys_acl_set_fd(vfs_handle_struct *handle,
    1213             :                                 files_struct *fsp,
    1214             :                                 SMB_ACL_TYPE_T type,
    1215             :                                 SMB_ACL_T theacl)
    1216             : {
    1217         248 :         struct catia_cache *cc = NULL;
    1218             :         int ret;
    1219             : 
    1220         248 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1221         248 :         if (ret != 0) {
    1222           0 :                 return ret;
    1223             :         }
    1224             : 
    1225         248 :         ret = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, type, theacl);
    1226             : 
    1227         248 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1228             : 
    1229         248 :         return ret;
    1230             : }
    1231             : 
    1232        4758 : static NTSTATUS catia_fget_nt_acl(vfs_handle_struct *handle,
    1233             :                                   files_struct *fsp,
    1234             :                                   uint32_t security_info,
    1235             :                                   TALLOC_CTX *mem_ctx,
    1236             :                                   struct security_descriptor **ppdesc)
    1237             : {
    1238        4758 :         struct catia_cache *cc = NULL;
    1239             :         NTSTATUS status;
    1240             :         int ret;
    1241             : 
    1242        4758 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1243        4758 :         if (ret != 0) {
    1244           0 :                 return map_nt_error_from_unix(errno);
    1245             :         }
    1246             : 
    1247        4758 :         status = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info,
    1248             :                                           mem_ctx, ppdesc);
    1249             : 
    1250        4758 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1251             : 
    1252        4758 :         return status;
    1253             : }
    1254             : 
    1255         188 : static NTSTATUS catia_fset_nt_acl(vfs_handle_struct *handle,
    1256             :                                   files_struct *fsp,
    1257             :                                   uint32_t security_info_sent,
    1258             :                                   const struct security_descriptor *psd)
    1259             : {
    1260         188 :         struct catia_cache *cc = NULL;
    1261             :         NTSTATUS status;
    1262             :         int ret;
    1263             : 
    1264         188 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1265         188 :         if (ret != 0) {
    1266           0 :                 return map_nt_error_from_unix(errno);
    1267             :         }
    1268             : 
    1269         188 :         status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
    1270             : 
    1271         188 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1272             : 
    1273         188 :         return status;
    1274             : }
    1275             : 
    1276         640 : static NTSTATUS catia_fset_dos_attributes(struct vfs_handle_struct *handle,
    1277             :                                           struct files_struct *fsp,
    1278             :                                           uint32_t dosmode)
    1279             : {
    1280         640 :         struct catia_cache *cc = NULL;
    1281             :         NTSTATUS status;
    1282             :         int ret;
    1283             : 
    1284         640 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1285         640 :         if (ret != 0) {
    1286           0 :                 return map_nt_error_from_unix(errno);
    1287             :         }
    1288             : 
    1289         640 :         status = SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, dosmode);
    1290             : 
    1291         640 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1292             : 
    1293         640 :         return status;
    1294             : }
    1295             : 
    1296        6066 : static NTSTATUS catia_fget_dos_attributes(struct vfs_handle_struct *handle,
    1297             :                                           struct files_struct *fsp,
    1298             :                                           uint32_t *dosmode)
    1299             : {
    1300        6066 :         struct catia_cache *cc = NULL;
    1301             :         NTSTATUS status;
    1302             :         int ret;
    1303             : 
    1304        6066 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1305        6066 :         if (ret != 0) {
    1306           0 :                 return map_nt_error_from_unix(errno);
    1307             :         }
    1308             : 
    1309        6066 :         status = SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
    1310             : 
    1311        6066 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1312             : 
    1313        6066 :         return status;
    1314             : }
    1315             : 
    1316         372 : static int catia_fchown(vfs_handle_struct *handle,
    1317             :                         files_struct *fsp,
    1318             :                         uid_t uid,
    1319             :                         gid_t gid)
    1320             : {
    1321         372 :         struct catia_cache *cc = NULL;
    1322             :         int ret;
    1323             : 
    1324         372 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1325         372 :         if (ret != 0) {
    1326           0 :                 return ret;
    1327             :         }
    1328             : 
    1329         372 :         ret = SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid);
    1330             : 
    1331         372 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1332             : 
    1333         372 :         return ret;
    1334             : }
    1335             : 
    1336           2 : static int catia_fchmod(vfs_handle_struct *handle,
    1337             :                         files_struct *fsp,
    1338             :                         mode_t mode)
    1339             : {
    1340           2 :         struct catia_cache *cc = NULL;
    1341             :         int ret;
    1342             : 
    1343           2 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1344           2 :         if (ret != 0) {
    1345           0 :                 return ret;
    1346             :         }
    1347             : 
    1348           2 :         ret = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
    1349             : 
    1350           2 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1351             : 
    1352           2 :         return ret;
    1353             : }
    1354             : 
    1355             : struct catia_pread_state {
    1356             :         ssize_t ret;
    1357             :         struct vfs_aio_state vfs_aio_state;
    1358             :         struct files_struct *fsp;
    1359             :         struct catia_cache *cc;
    1360             : };
    1361             : 
    1362             : static void catia_pread_done(struct tevent_req *subreq);
    1363             : 
    1364           8 : static struct tevent_req *catia_pread_send(struct vfs_handle_struct *handle,
    1365             :                                            TALLOC_CTX *mem_ctx,
    1366             :                                            struct tevent_context *ev,
    1367             :                                            struct files_struct *fsp,
    1368             :                                            void *data,
    1369             :                                            size_t n,
    1370             :                                            off_t offset)
    1371             : {
    1372           8 :         struct tevent_req *req = NULL, *subreq = NULL;
    1373           8 :         struct catia_pread_state *state = NULL;
    1374             :         int ret;
    1375             : 
    1376           8 :         req = tevent_req_create(mem_ctx, &state,
    1377             :                                 struct catia_pread_state);
    1378           8 :         if (req == NULL) {
    1379           0 :                 return NULL;
    1380             :         }
    1381           8 :         state->fsp = fsp;
    1382             : 
    1383           8 :         ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
    1384           8 :         if (ret != 0) {
    1385           0 :                 tevent_req_error(req, errno);
    1386           0 :                 return tevent_req_post(req, ev);
    1387             :         }
    1388             : 
    1389           8 :         subreq = SMB_VFS_NEXT_PREAD_SEND(state, ev, handle, fsp, data,
    1390             :                                          n, offset);
    1391           8 :         if (tevent_req_nomem(subreq, req)) {
    1392           0 :                 return tevent_req_post(req, ev);
    1393             :         }
    1394           8 :         tevent_req_set_callback(subreq, catia_pread_done, req);
    1395             : 
    1396           8 :         return req;
    1397             : }
    1398             : 
    1399           8 : static void catia_pread_done(struct tevent_req *subreq)
    1400             : {
    1401           8 :         struct tevent_req *req = tevent_req_callback_data(
    1402             :                 subreq, struct tevent_req);
    1403           8 :         struct catia_pread_state *state = tevent_req_data(
    1404             :                 req, struct catia_pread_state);
    1405             : 
    1406           8 :         state->ret = SMB_VFS_PREAD_RECV(subreq, &state->vfs_aio_state);
    1407           8 :         TALLOC_FREE(subreq);
    1408             : 
    1409           8 :         CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
    1410             : 
    1411           8 :         tevent_req_done(req);
    1412           8 : }
    1413             : 
    1414           8 : static ssize_t catia_pread_recv(struct tevent_req *req,
    1415             :                                 struct vfs_aio_state *vfs_aio_state)
    1416             : {
    1417           8 :         struct catia_pread_state *state = tevent_req_data(
    1418             :                 req, struct catia_pread_state);
    1419             : 
    1420           8 :         if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
    1421           0 :                 return -1;
    1422             :         }
    1423             : 
    1424           8 :         *vfs_aio_state = state->vfs_aio_state;
    1425           8 :         return state->ret;
    1426             : }
    1427             : 
    1428             : struct catia_pwrite_state {
    1429             :         ssize_t ret;
    1430             :         struct vfs_aio_state vfs_aio_state;
    1431             :         struct files_struct *fsp;
    1432             :         struct catia_cache *cc;
    1433             : };
    1434             : 
    1435             : static void catia_pwrite_done(struct tevent_req *subreq);
    1436             : 
    1437          16 : static struct tevent_req *catia_pwrite_send(struct vfs_handle_struct *handle,
    1438             :                                             TALLOC_CTX *mem_ctx,
    1439             :                                             struct tevent_context *ev,
    1440             :                                             struct files_struct *fsp,
    1441             :                                             const void *data,
    1442             :                                             size_t n,
    1443             :                                             off_t offset)
    1444             : {
    1445          16 :         struct tevent_req *req = NULL, *subreq = NULL;
    1446          16 :         struct catia_pwrite_state *state = NULL;
    1447             :         int ret;
    1448             : 
    1449          16 :         req = tevent_req_create(mem_ctx, &state,
    1450             :                                 struct catia_pwrite_state);
    1451          16 :         if (req == NULL) {
    1452           0 :                 return NULL;
    1453             :         }
    1454          16 :         state->fsp = fsp;
    1455             : 
    1456          16 :         ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
    1457          16 :         if (ret != 0) {
    1458           0 :                 tevent_req_error(req, errno);
    1459           0 :                 return tevent_req_post(req, ev);
    1460             :         }
    1461             : 
    1462          16 :         subreq = SMB_VFS_NEXT_PWRITE_SEND(state, ev, handle, fsp, data,
    1463             :                                           n, offset);
    1464          16 :         if (tevent_req_nomem(subreq, req)) {
    1465           0 :                 return tevent_req_post(req, ev);
    1466             :         }
    1467          16 :         tevent_req_set_callback(subreq, catia_pwrite_done, req);
    1468             : 
    1469          16 :         return req;
    1470             : }
    1471             : 
    1472          16 : static void catia_pwrite_done(struct tevent_req *subreq)
    1473             : {
    1474          16 :         struct tevent_req *req = tevent_req_callback_data(
    1475             :                 subreq, struct tevent_req);
    1476          16 :         struct catia_pwrite_state *state = tevent_req_data(
    1477             :                 req, struct catia_pwrite_state);
    1478             : 
    1479          16 :         state->ret = SMB_VFS_PWRITE_RECV(subreq, &state->vfs_aio_state);
    1480          16 :         TALLOC_FREE(subreq);
    1481             : 
    1482          16 :         CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
    1483             : 
    1484          16 :         tevent_req_done(req);
    1485          16 : }
    1486             : 
    1487          16 : static ssize_t catia_pwrite_recv(struct tevent_req *req,
    1488             :                                 struct vfs_aio_state *vfs_aio_state)
    1489             : {
    1490          16 :         struct catia_pwrite_state *state = tevent_req_data(
    1491             :                 req, struct catia_pwrite_state);
    1492             : 
    1493          16 :         if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
    1494           0 :                 return -1;
    1495             :         }
    1496             : 
    1497          16 :         *vfs_aio_state = state->vfs_aio_state;
    1498          16 :         return state->ret;
    1499             : }
    1500             : 
    1501           0 : static off_t catia_lseek(vfs_handle_struct *handle,
    1502             :                          files_struct *fsp,
    1503             :                          off_t offset,
    1504             :                          int whence)
    1505             : {
    1506           0 :         struct catia_cache *cc = NULL;
    1507             :         ssize_t result;
    1508             :         int ret;
    1509             : 
    1510           0 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1511           0 :         if (ret != 0) {
    1512           0 :                 return -1;
    1513             :         }
    1514             : 
    1515           0 :         result = SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence);
    1516             : 
    1517           0 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1518             : 
    1519           0 :         return result;
    1520             : }
    1521             : 
    1522             : struct catia_fsync_state {
    1523             :         int ret;
    1524             :         struct vfs_aio_state vfs_aio_state;
    1525             :         struct files_struct *fsp;
    1526             :         struct catia_cache *cc;
    1527             : };
    1528             : 
    1529             : static void catia_fsync_done(struct tevent_req *subreq);
    1530             : 
    1531           0 : static struct tevent_req *catia_fsync_send(struct vfs_handle_struct *handle,
    1532             :                                            TALLOC_CTX *mem_ctx,
    1533             :                                            struct tevent_context *ev,
    1534             :                                            struct files_struct *fsp)
    1535             : {
    1536           0 :         struct tevent_req *req = NULL, *subreq = NULL;
    1537           0 :         struct catia_fsync_state *state = NULL;
    1538             :         int ret;
    1539             : 
    1540           0 :         req = tevent_req_create(mem_ctx, &state,
    1541             :                                 struct catia_fsync_state);
    1542           0 :         if (req == NULL) {
    1543           0 :                 return NULL;
    1544             :         }
    1545           0 :         state->fsp = fsp;
    1546             : 
    1547           0 :         ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
    1548           0 :         if (ret != 0) {
    1549           0 :                 tevent_req_error(req, errno);
    1550           0 :                 return tevent_req_post(req, ev);
    1551             :         }
    1552             : 
    1553           0 :         subreq = SMB_VFS_NEXT_FSYNC_SEND(state, ev, handle, fsp);
    1554           0 :         if (tevent_req_nomem(subreq, req)) {
    1555           0 :                 return tevent_req_post(req, ev);
    1556             :         }
    1557           0 :         tevent_req_set_callback(subreq, catia_fsync_done, req);
    1558             : 
    1559           0 :         return req;
    1560             : }
    1561             : 
    1562           0 : static void catia_fsync_done(struct tevent_req *subreq)
    1563             : {
    1564           0 :         struct tevent_req *req = tevent_req_callback_data(
    1565             :                 subreq, struct tevent_req);
    1566           0 :         struct catia_fsync_state *state = tevent_req_data(
    1567             :                 req, struct catia_fsync_state);
    1568             : 
    1569           0 :         state->ret = SMB_VFS_FSYNC_RECV(subreq, &state->vfs_aio_state);
    1570           0 :         TALLOC_FREE(subreq);
    1571             : 
    1572           0 :         CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
    1573             : 
    1574           0 :         tevent_req_done(req);
    1575           0 : }
    1576             : 
    1577           0 : static int catia_fsync_recv(struct tevent_req *req,
    1578             :                             struct vfs_aio_state *vfs_aio_state)
    1579             : {
    1580           0 :         struct catia_fsync_state *state = tevent_req_data(
    1581             :                 req, struct catia_fsync_state);
    1582             : 
    1583           0 :         if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
    1584           0 :                 return -1;
    1585             :         }
    1586             : 
    1587           0 :         *vfs_aio_state = state->vfs_aio_state;
    1588           0 :         return state->ret;
    1589             : }
    1590             : 
    1591        1330 : static bool catia_lock(vfs_handle_struct *handle,
    1592             :                        files_struct *fsp,
    1593             :                        int op,
    1594             :                        off_t offset,
    1595             :                        off_t count,
    1596             :                        int type)
    1597             : {
    1598        1330 :         struct catia_cache *cc = NULL;
    1599             :         bool ok;
    1600             :         int ret;
    1601             : 
    1602        1330 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1603        1330 :         if (ret != 0) {
    1604           0 :                 return false;
    1605             :         }
    1606             : 
    1607        1330 :         ok = SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type);
    1608             : 
    1609        1330 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1610             : 
    1611        1330 :         return ok;
    1612             : }
    1613             : 
    1614           0 : static int catia_filesystem_sharemode(struct vfs_handle_struct *handle,
    1615             :                                       struct files_struct *fsp,
    1616             :                                       uint32_t share_access,
    1617             :                                       uint32_t access_mask)
    1618             : {
    1619           0 :         struct catia_cache *cc = NULL;
    1620             :         int ret;
    1621             : 
    1622           0 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1623           0 :         if (ret != 0) {
    1624           0 :                 return -1;
    1625             :         }
    1626             : 
    1627           0 :         ret = SMB_VFS_NEXT_FILESYSTEM_SHAREMODE(handle,
    1628             :                                                 fsp,
    1629             :                                                 share_access,
    1630             :                                                 access_mask);
    1631             : 
    1632           0 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1633             : 
    1634           0 :         return ret;
    1635             : }
    1636             : 
    1637           0 : static int catia_linux_setlease(vfs_handle_struct *handle,
    1638             :                                 files_struct *fsp,
    1639             :                                 int leasetype)
    1640             : {
    1641           0 :         struct catia_cache *cc = NULL;
    1642             :         int ret;
    1643             : 
    1644           0 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1645           0 :         if (ret != 0) {
    1646           0 :                 return -1;
    1647             :         }
    1648             : 
    1649           0 :         ret = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype);
    1650             : 
    1651           0 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1652             : 
    1653           0 :         return ret;
    1654             : }
    1655             : 
    1656        2994 : static bool catia_getlock(vfs_handle_struct *handle,
    1657             :                           files_struct *fsp,
    1658             :                           off_t *poffset,
    1659             :                           off_t *pcount,
    1660             :                           int *ptype,
    1661             :                           pid_t *ppid)
    1662             : {
    1663        2994 :         struct catia_cache *cc = NULL;
    1664             :         int ret;
    1665             :         bool ok;
    1666             : 
    1667        2994 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1668        2994 :         if (ret != 0) {
    1669           0 :                 return false;
    1670             :         }
    1671             : 
    1672        2994 :         ok = SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid);
    1673             : 
    1674        2994 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1675             : 
    1676        2994 :         return ok;
    1677             : }
    1678             : 
    1679         926 : static bool catia_strict_lock_check(struct vfs_handle_struct *handle,
    1680             :                                     struct files_struct *fsp,
    1681             :                                     struct lock_struct *plock)
    1682             : {
    1683         926 :         struct catia_cache *cc = NULL;
    1684             :         int ret;
    1685             :         bool ok;
    1686             : 
    1687         926 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1688         926 :         if (ret != 0) {
    1689           0 :                 return false;
    1690             :         }
    1691             : 
    1692         926 :         ok = SMB_VFS_NEXT_STRICT_LOCK_CHECK(handle, fsp, plock);
    1693             : 
    1694         926 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1695             : 
    1696         926 :         return ok;
    1697             : }
    1698             : 
    1699           0 : static NTSTATUS catia_fsctl(struct vfs_handle_struct *handle,
    1700             :                             struct files_struct *fsp,
    1701             :                             TALLOC_CTX *ctx,
    1702             :                             uint32_t function,
    1703             :                             uint16_t req_flags,
    1704             :                             const uint8_t *_in_data,
    1705             :                             uint32_t in_len,
    1706             :                             uint8_t **_out_data,
    1707             :                             uint32_t max_out_len,
    1708             :                             uint32_t *out_len)
    1709             : {
    1710             :         NTSTATUS result;
    1711           0 :         struct catia_cache *cc = NULL;
    1712             :         int ret;
    1713             : 
    1714           0 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1715           0 :         if (ret != 0) {
    1716           0 :                 return map_nt_error_from_unix(errno);
    1717             :         }
    1718             : 
    1719           0 :         result = SMB_VFS_NEXT_FSCTL(handle,
    1720             :                                 fsp,
    1721             :                                 ctx,
    1722             :                                 function,
    1723             :                                 req_flags,
    1724             :                                 _in_data,
    1725             :                                 in_len,
    1726             :                                 _out_data,
    1727             :                                 max_out_len,
    1728             :                                 out_len);
    1729             : 
    1730           0 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1731             : 
    1732           0 :         return result;
    1733             : }
    1734             : 
    1735           0 : static NTSTATUS catia_fget_compression(vfs_handle_struct *handle,
    1736             :                                       TALLOC_CTX *mem_ctx,
    1737             :                                       struct files_struct *fsp,
    1738             :                                       uint16_t *_compression_fmt)
    1739             : {
    1740             :         NTSTATUS result;
    1741           0 :         struct catia_cache *cc = NULL;
    1742             :         int ret;
    1743             : 
    1744           0 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1745           0 :         if (ret != 0) {
    1746           0 :                 return map_nt_error_from_unix(errno);
    1747             :         }
    1748             : 
    1749           0 :         result = SMB_VFS_NEXT_FGET_COMPRESSION(handle,
    1750             :                                         mem_ctx,
    1751             :                                         fsp,
    1752             :                                         _compression_fmt);
    1753             : 
    1754           0 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1755             : 
    1756           0 :         return result;
    1757             : }
    1758             : 
    1759           0 : static NTSTATUS catia_set_compression(vfs_handle_struct *handle,
    1760             :                                       TALLOC_CTX *mem_ctx,
    1761             :                                       struct files_struct *fsp,
    1762             :                                       uint16_t compression_fmt)
    1763             : {
    1764             :         NTSTATUS result;
    1765           0 :         struct catia_cache *cc = NULL;
    1766             :         int ret;
    1767             : 
    1768           0 :         ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
    1769           0 :         if (ret != 0) {
    1770           0 :                 return map_nt_error_from_unix(errno);
    1771             :         }
    1772             : 
    1773           0 :         result = SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp,
    1774             :                                               compression_fmt);
    1775             : 
    1776           0 :         CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
    1777             : 
    1778           0 :         return result;
    1779             : }
    1780             : 
    1781           0 : static NTSTATUS catia_create_dfs_pathat(struct vfs_handle_struct *handle,
    1782             :                         struct files_struct *dirfsp,
    1783             :                         const struct smb_filename *smb_fname,
    1784             :                         const struct referral *reflist,
    1785             :                         size_t referral_count)
    1786             : {
    1787           0 :         char *mapped_name = NULL;
    1788           0 :         const char *path = smb_fname->base_name;
    1789           0 :         struct smb_filename *mapped_smb_fname = NULL;
    1790             :         NTSTATUS status;
    1791             : 
    1792           0 :         status = catia_string_replace_allocate(handle->conn,
    1793             :                                         path,
    1794             :                                         &mapped_name,
    1795             :                                         vfs_translate_to_unix);
    1796           0 :         if (!NT_STATUS_IS_OK(status)) {
    1797           0 :                 errno = map_errno_from_nt_status(status);
    1798           0 :                 return status;
    1799             :         }
    1800           0 :         mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
    1801             :                                         mapped_name,
    1802             :                                         NULL,
    1803             :                                         &smb_fname->st,
    1804             :                                         smb_fname->twrp,
    1805             :                                         smb_fname->flags);
    1806           0 :         if (mapped_smb_fname == NULL) {
    1807           0 :                 TALLOC_FREE(mapped_name);
    1808           0 :                 return NT_STATUS_NO_MEMORY;
    1809             :         }
    1810             : 
    1811           0 :         status = SMB_VFS_NEXT_CREATE_DFS_PATHAT(handle,
    1812             :                                         dirfsp,
    1813             :                                         mapped_smb_fname,
    1814             :                                         reflist,
    1815             :                                         referral_count);
    1816           0 :         TALLOC_FREE(mapped_name);
    1817           0 :         TALLOC_FREE(mapped_smb_fname);
    1818           0 :         return status;
    1819             : }
    1820             : 
    1821           0 : static NTSTATUS catia_read_dfs_pathat(struct vfs_handle_struct *handle,
    1822             :                         TALLOC_CTX *mem_ctx,
    1823             :                         struct files_struct *dirfsp,
    1824             :                         struct smb_filename *smb_fname,
    1825             :                         struct referral **ppreflist,
    1826             :                         size_t *preferral_count)
    1827             : {
    1828           0 :         char *mapped_name = NULL;
    1829           0 :         const char *path = smb_fname->base_name;
    1830           0 :         struct smb_filename *mapped_smb_fname = NULL;
    1831             :         NTSTATUS status;
    1832             : 
    1833           0 :         status = catia_string_replace_allocate(handle->conn,
    1834             :                                         path,
    1835             :                                         &mapped_name,
    1836             :                                         vfs_translate_to_unix);
    1837           0 :         if (!NT_STATUS_IS_OK(status)) {
    1838           0 :                 errno = map_errno_from_nt_status(status);
    1839           0 :                 return status;
    1840             :         }
    1841           0 :         mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
    1842             :                                         mapped_name,
    1843             :                                         NULL,
    1844           0 :                                         &smb_fname->st,
    1845             :                                         smb_fname->twrp,
    1846             :                                         smb_fname->flags);
    1847           0 :         if (mapped_smb_fname == NULL) {
    1848           0 :                 TALLOC_FREE(mapped_name);
    1849           0 :                 return NT_STATUS_NO_MEMORY;
    1850             :         }
    1851             : 
    1852           0 :         status = SMB_VFS_NEXT_READ_DFS_PATHAT(handle,
    1853             :                                         mem_ctx,
    1854             :                                         dirfsp,
    1855             :                                         mapped_smb_fname,
    1856             :                                         ppreflist,
    1857             :                                         preferral_count);
    1858           0 :         if (NT_STATUS_IS_OK(status)) {
    1859             :                 /* Return any stat(2) info. */
    1860           0 :                 smb_fname->st = mapped_smb_fname->st;
    1861             :         }
    1862             : 
    1863           0 :         TALLOC_FREE(mapped_name);
    1864           0 :         TALLOC_FREE(mapped_smb_fname);
    1865           0 :         return status;
    1866             : }
    1867             : 
    1868             : static struct vfs_fn_pointers vfs_catia_fns = {
    1869             :         .connect_fn = catia_connect,
    1870             : 
    1871             :         /* Directory operations */
    1872             :         .mkdirat_fn = catia_mkdirat,
    1873             : 
    1874             :         /* File operations */
    1875             :         .openat_fn = catia_openat,
    1876             :         .pread_fn = catia_pread,
    1877             :         .pread_send_fn = catia_pread_send,
    1878             :         .pread_recv_fn = catia_pread_recv,
    1879             :         .pwrite_fn = catia_pwrite,
    1880             :         .pwrite_send_fn = catia_pwrite_send,
    1881             :         .pwrite_recv_fn = catia_pwrite_recv,
    1882             :         .lseek_fn = catia_lseek,
    1883             :         .renameat_fn = catia_renameat,
    1884             :         .fsync_send_fn = catia_fsync_send,
    1885             :         .fsync_recv_fn = catia_fsync_recv,
    1886             :         .stat_fn = catia_stat,
    1887             :         .fstat_fn = catia_fstat,
    1888             :         .lstat_fn = catia_lstat,
    1889             :         .unlinkat_fn = catia_unlinkat,
    1890             :         .fchmod_fn = catia_fchmod,
    1891             :         .fchown_fn = catia_fchown,
    1892             :         .lchown_fn = catia_lchown,
    1893             :         .chdir_fn = catia_chdir,
    1894             :         .fntimes_fn = catia_fntimes,
    1895             :         .ftruncate_fn = catia_ftruncate,
    1896             :         .fallocate_fn = catia_fallocate,
    1897             :         .lock_fn = catia_lock,
    1898             :         .filesystem_sharemode_fn = catia_filesystem_sharemode,
    1899             :         .linux_setlease_fn = catia_linux_setlease,
    1900             :         .getlock_fn = catia_getlock,
    1901             :         .realpath_fn = catia_realpath,
    1902             :         .fstreaminfo_fn = catia_fstreaminfo,
    1903             :         .strict_lock_check_fn = catia_strict_lock_check,
    1904             :         .translate_name_fn = catia_translate_name,
    1905             :         .fsctl_fn = catia_fsctl,
    1906             :         .get_dos_attributes_send_fn = vfs_not_implemented_get_dos_attributes_send,
    1907             :         .get_dos_attributes_recv_fn = vfs_not_implemented_get_dos_attributes_recv,
    1908             :         .fset_dos_attributes_fn = catia_fset_dos_attributes,
    1909             :         .fget_dos_attributes_fn = catia_fget_dos_attributes,
    1910             :         .fget_compression_fn = catia_fget_compression,
    1911             :         .set_compression_fn = catia_set_compression,
    1912             :         .create_dfs_pathat_fn = catia_create_dfs_pathat,
    1913             :         .read_dfs_pathat_fn = catia_read_dfs_pathat,
    1914             : 
    1915             :         /* NT ACL operations. */
    1916             :         .fget_nt_acl_fn = catia_fget_nt_acl,
    1917             :         .fset_nt_acl_fn = catia_fset_nt_acl,
    1918             : 
    1919             :         /* POSIX ACL operations. */
    1920             :         .sys_acl_get_fd_fn = catia_sys_acl_get_fd,
    1921             :         .sys_acl_blob_get_fd_fn = catia_sys_acl_blob_get_fd,
    1922             :         .sys_acl_set_fd_fn = catia_sys_acl_set_fd,
    1923             : 
    1924             :         /* EA operations. */
    1925             :         .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
    1926             :         .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
    1927             :         .fgetxattr_fn = catia_fgetxattr,
    1928             :         .flistxattr_fn = catia_flistxattr,
    1929             :         .fremovexattr_fn = catia_fremovexattr,
    1930             :         .fsetxattr_fn = catia_fsetxattr,
    1931             : };
    1932             : 
    1933             : static_decl_vfs;
    1934         108 : NTSTATUS vfs_catia_init(TALLOC_CTX *ctx)
    1935             : {
    1936             :         NTSTATUS ret;
    1937             : 
    1938         108 :         ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "catia",
    1939             :                                 &vfs_catia_fns);
    1940         108 :         if (!NT_STATUS_IS_OK(ret))
    1941           0 :                 return ret;
    1942             : 
    1943         108 :         vfs_catia_debug_level = debug_add_class("catia");
    1944         108 :         if (vfs_catia_debug_level == -1) {
    1945           0 :                 vfs_catia_debug_level = DBGC_VFS;
    1946           0 :                 DEBUG(0, ("vfs_catia: Couldn't register custom debugging "
    1947             :                           "class!\n"));
    1948             :         } else {
    1949         108 :                 DEBUG(10, ("vfs_catia: Debug class number of "
    1950             :                            "'catia': %d\n", vfs_catia_debug_level));
    1951             :         }
    1952             : 
    1953         108 :         return ret;
    1954             : 
    1955             : }

Generated by: LCOV version 1.13