LCOV - code coverage report
Current view: top level - source3/modules - vfs_catia.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 540 789 68.4 %
Date: 2024-04-13 12:30:31 Functions: 51 62 82.3 %

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

Generated by: LCOV version 1.14