LCOV - code coverage report
Current view: top level - source3/modules - vfs_cap.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 2 470 0.4 %
Date: 2021-09-23 10:06:22 Functions: 1 24 4.2 %

          Line data    Source code
       1             : /*
       2             :  * CAP VFS module for Samba 3.x Version 0.3
       3             :  *
       4             :  * Copyright (C) Tim Potter, 1999-2000
       5             :  * Copyright (C) Alexander Bokovoy, 2002-2003
       6             :  * Copyright (C) Stefan (metze) Metzmacher, 2003
       7             :  * Copyright (C) TAKAHASHI Motonobu (monyo), 2003
       8             :  * Copyright (C) Jeremy Allison, 2007
       9             :  *
      10             :  * This program is free software; you can redistribute it and/or modify
      11             :  * it under the terms of the GNU General Public License as published by
      12             :  * the Free Software Foundation; either version 3 of the License, or
      13             :  * (at your option) any later version.
      14             :  *
      15             :  * This program is distributed in the hope that it will be useful,
      16             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :  * GNU General Public License for more details.
      19             :  *
      20             :  * You should have received a copy of the GNU General Public License
      21             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      22             :  */
      23             : 
      24             : 
      25             : #include "includes.h"
      26             : #include "smbd/smbd.h"
      27             : 
      28             : /* cap functions */
      29             : static char *capencode(TALLOC_CTX *ctx, const char *from);
      30             : static char *capdecode(TALLOC_CTX *ctx, const char *from);
      31             : 
      32           0 : static uint64_t cap_disk_free(vfs_handle_struct *handle,
      33             :                         const struct smb_filename *smb_fname,
      34             :                         uint64_t *bsize,
      35             :                         uint64_t *dfree,
      36             :                         uint64_t *dsize)
      37             : {
      38           0 :         char *capname = capencode(talloc_tos(), smb_fname->base_name);
      39           0 :         struct smb_filename *cap_smb_fname = NULL;
      40             : 
      41           0 :         if (!capname) {
      42           0 :                 errno = ENOMEM;
      43           0 :                 return (uint64_t)-1;
      44             :         }
      45           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
      46             :                                         capname,
      47             :                                         NULL,
      48             :                                         NULL,
      49             :                                         smb_fname->twrp,
      50             :                                         smb_fname->flags);
      51           0 :         if (cap_smb_fname == NULL) {
      52           0 :                 TALLOC_FREE(capname);
      53           0 :                 errno = ENOMEM;
      54           0 :                 return (uint64_t)-1;
      55             :         }
      56           0 :         return SMB_VFS_NEXT_DISK_FREE(handle, cap_smb_fname,
      57             :                         bsize, dfree, dsize);
      58             : }
      59             : 
      60           0 : static int cap_get_quota(vfs_handle_struct *handle,
      61             :                         const struct smb_filename *smb_fname,
      62             :                         enum SMB_QUOTA_TYPE qtype,
      63             :                         unid_t id,
      64             :                         SMB_DISK_QUOTA *dq)
      65             : {
      66           0 :         char *cappath = capencode(talloc_tos(), smb_fname->base_name);
      67           0 :         struct smb_filename *cap_smb_fname = NULL;
      68             : 
      69           0 :         if (!cappath) {
      70           0 :                 errno = ENOMEM;
      71           0 :                 return -1;
      72             :         }
      73           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
      74             :                                         cappath,
      75             :                                         NULL,
      76             :                                         NULL,
      77             :                                         smb_fname->twrp,
      78             :                                         smb_fname->flags);
      79           0 :         if (cap_smb_fname == NULL) {
      80           0 :                 TALLOC_FREE(cappath);
      81           0 :                 errno = ENOMEM;
      82           0 :                 return -1;
      83             :         }
      84           0 :         return SMB_VFS_NEXT_GET_QUOTA(handle, cap_smb_fname, qtype, id, dq);
      85             : }
      86             : 
      87           0 : static struct dirent *cap_readdir(vfs_handle_struct *handle,
      88             :                                   struct files_struct *dirfsp,
      89             :                                   DIR *dirp,
      90             :                                   SMB_STRUCT_STAT *sbuf)
      91             : {
      92             :         struct dirent *result;
      93             :         struct dirent *newdirent;
      94             :         char *newname;
      95             :         size_t newnamelen;
      96           0 :         DEBUG(3,("cap: cap_readdir\n"));
      97             : 
      98           0 :         result = SMB_VFS_NEXT_READDIR(handle, dirfsp, dirp, NULL);
      99           0 :         if (!result) {
     100           0 :                 return NULL;
     101             :         }
     102             : 
     103           0 :         newname = capdecode(talloc_tos(), result->d_name);
     104           0 :         if (!newname) {
     105           0 :                 return NULL;
     106             :         }
     107           0 :         DEBUG(3,("cap: cap_readdir: %s\n", newname));
     108           0 :         newnamelen = strlen(newname)+1;
     109           0 :         newdirent = talloc_size(
     110             :                 talloc_tos(), sizeof(struct dirent) + newnamelen);
     111           0 :         if (!newdirent) {
     112           0 :                 return NULL;
     113             :         }
     114           0 :         talloc_set_name_const(newdirent, "struct dirent");
     115           0 :         memcpy(newdirent, result, sizeof(struct dirent));
     116           0 :         memcpy(&newdirent->d_name, newname, newnamelen);
     117           0 :         return newdirent;
     118             : }
     119             : 
     120           0 : static int cap_mkdirat(vfs_handle_struct *handle,
     121             :                 struct files_struct *dirfsp,
     122             :                 const struct smb_filename *smb_fname,
     123             :                 mode_t mode)
     124             : {
     125           0 :         char *cappath = capencode(talloc_tos(), smb_fname->base_name);
     126           0 :         struct smb_filename *cap_smb_fname = NULL;
     127             : 
     128           0 :         if (!cappath) {
     129           0 :                 errno = ENOMEM;
     130           0 :                 return -1;
     131             :         }
     132             : 
     133           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     134             :                                         cappath,
     135             :                                         NULL,
     136             :                                         NULL,
     137             :                                         smb_fname->twrp,
     138             :                                         smb_fname->flags);
     139           0 :         if (cap_smb_fname == NULL) {
     140           0 :                 TALLOC_FREE(cappath);
     141           0 :                 errno = ENOMEM;
     142           0 :                 return -1;
     143             :         }
     144             : 
     145           0 :         return SMB_VFS_NEXT_MKDIRAT(handle,
     146             :                         dirfsp,
     147             :                         cap_smb_fname,
     148             :                         mode);
     149             : }
     150             : 
     151           0 : static int cap_openat(vfs_handle_struct *handle,
     152             :                       const struct files_struct *dirfsp,
     153             :                       const struct smb_filename *smb_fname_in,
     154             :                       files_struct *fsp,
     155             :                       int flags,
     156             :                       mode_t mode)
     157             : {
     158           0 :         char *cappath = NULL;
     159           0 :         struct smb_filename *smb_fname = NULL;
     160             :         int ret;
     161           0 :         int saved_errno = 0;
     162             : 
     163           0 :         cappath = capencode(talloc_tos(), smb_fname_in->base_name);
     164           0 :         if (cappath == NULL) {
     165           0 :                 errno = ENOMEM;
     166           0 :                 return -1;
     167             :         }
     168             : 
     169           0 :         smb_fname = cp_smb_filename(talloc_tos(), smb_fname_in);
     170           0 :         if (smb_fname == NULL) {
     171           0 :                 TALLOC_FREE(cappath);
     172           0 :                 errno = ENOMEM;
     173           0 :                 return -1;
     174             :         }
     175           0 :         smb_fname->base_name = cappath;
     176             : 
     177           0 :         DBG_DEBUG("cap_open for %s\n", smb_fname_str_dbg(smb_fname));
     178           0 :         ret = SMB_VFS_NEXT_OPENAT(handle,
     179             :                                   dirfsp,
     180             :                                   smb_fname,
     181             :                                   fsp,
     182             :                                   flags,
     183             :                                   mode);
     184             : 
     185           0 :         if (ret == -1) {
     186           0 :                 saved_errno = errno;
     187             :         }
     188           0 :         TALLOC_FREE(cappath);
     189           0 :         TALLOC_FREE(smb_fname);
     190           0 :         if (saved_errno != 0) {
     191           0 :                 errno = saved_errno;
     192             :         }
     193           0 :         return ret;
     194             : }
     195             : 
     196           0 : static int cap_renameat(vfs_handle_struct *handle,
     197             :                         files_struct *srcfsp,
     198             :                         const struct smb_filename *smb_fname_src,
     199             :                         files_struct *dstfsp,
     200             :                         const struct smb_filename *smb_fname_dst)
     201             : {
     202           0 :         char *capold = NULL;
     203           0 :         char *capnew = NULL;
     204           0 :         struct smb_filename *smb_fname_src_tmp = NULL;
     205           0 :         struct smb_filename *smb_fname_dst_tmp = NULL;
     206           0 :         struct smb_filename *full_fname_src = NULL;
     207           0 :         struct smb_filename *full_fname_dst = NULL;
     208           0 :         int ret = -1;
     209           0 :         int saved_errno = 0;
     210             : 
     211           0 :         full_fname_src = full_path_from_dirfsp_atname(talloc_tos(),
     212             :                                                   srcfsp,
     213             :                                                   smb_fname_src);
     214           0 :         if (full_fname_src == NULL) {
     215           0 :                 errno = ENOMEM;
     216           0 :                 goto out;
     217             :         }
     218             : 
     219           0 :         full_fname_dst = full_path_from_dirfsp_atname(talloc_tos(),
     220             :                                                   dstfsp,
     221             :                                                   smb_fname_dst);
     222           0 :         if (full_fname_dst == NULL) {
     223           0 :                 errno = ENOMEM;
     224           0 :                 goto out;
     225             :         }
     226             : 
     227           0 :         capold = capencode(talloc_tos(), full_fname_src->base_name);
     228           0 :         capnew = capencode(talloc_tos(), full_fname_dst->base_name);
     229           0 :         if (!capold || !capnew) {
     230           0 :                 errno = ENOMEM;
     231           0 :                 goto out;
     232             :         }
     233             : 
     234             :         /* Setup temporary smb_filename structs. */
     235           0 :         smb_fname_src_tmp = cp_smb_filename(talloc_tos(), full_fname_src);
     236           0 :         if (smb_fname_src_tmp == NULL) {
     237           0 :                 errno = ENOMEM;
     238           0 :                 goto out;
     239             :         }
     240           0 :         smb_fname_dst_tmp = cp_smb_filename(talloc_tos(), full_fname_dst);
     241           0 :         if (smb_fname_dst_tmp == NULL) {
     242           0 :                 errno = ENOMEM;
     243           0 :                 goto out;
     244             :         }
     245             : 
     246           0 :         smb_fname_src_tmp->base_name = capold;
     247           0 :         smb_fname_dst_tmp->base_name = capnew;
     248             : 
     249           0 :         ret = SMB_VFS_NEXT_RENAMEAT(handle,
     250             :                                 srcfsp->conn->cwd_fsp,
     251             :                                 smb_fname_src_tmp,
     252             :                                 dstfsp->conn->cwd_fsp,
     253             :                                 smb_fname_dst_tmp);
     254             : 
     255           0 :  out:
     256             : 
     257           0 :         if (ret != 0) {
     258           0 :                 saved_errno = errno;
     259             :         }
     260             : 
     261           0 :         TALLOC_FREE(full_fname_src);
     262           0 :         TALLOC_FREE(full_fname_dst);
     263           0 :         TALLOC_FREE(capold);
     264           0 :         TALLOC_FREE(capnew);
     265           0 :         TALLOC_FREE(smb_fname_src_tmp);
     266           0 :         TALLOC_FREE(smb_fname_dst_tmp);
     267             : 
     268           0 :         if (ret != 0) {
     269           0 :                 errno = saved_errno;
     270             :         }
     271             : 
     272           0 :         return ret;
     273             : }
     274             : 
     275           0 : static int cap_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
     276             : {
     277             :         char *cappath;
     278           0 :         char *tmp_base_name = NULL;
     279             :         int ret;
     280             : 
     281           0 :         cappath = capencode(talloc_tos(), smb_fname->base_name);
     282             : 
     283           0 :         if (!cappath) {
     284           0 :                 errno = ENOMEM;
     285           0 :                 return -1;
     286             :         }
     287             : 
     288           0 :         tmp_base_name = smb_fname->base_name;
     289           0 :         smb_fname->base_name = cappath;
     290             : 
     291           0 :         ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
     292             : 
     293           0 :         smb_fname->base_name = tmp_base_name;
     294           0 :         TALLOC_FREE(cappath);
     295             : 
     296           0 :         return ret;
     297             : }
     298             : 
     299           0 : static int cap_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
     300             : {
     301             :         char *cappath;
     302           0 :         char *tmp_base_name = NULL;
     303             :         int ret;
     304             : 
     305           0 :         cappath = capencode(talloc_tos(), smb_fname->base_name);
     306             : 
     307           0 :         if (!cappath) {
     308           0 :                 errno = ENOMEM;
     309           0 :                 return -1;
     310             :         }
     311             : 
     312           0 :         tmp_base_name = smb_fname->base_name;
     313           0 :         smb_fname->base_name = cappath;
     314             : 
     315           0 :         ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
     316             : 
     317           0 :         smb_fname->base_name = tmp_base_name;
     318           0 :         TALLOC_FREE(cappath);
     319             : 
     320           0 :         return ret;
     321             : }
     322             : 
     323           0 : static int cap_unlinkat(vfs_handle_struct *handle,
     324             :                         struct files_struct *dirfsp,
     325             :                         const struct smb_filename *smb_fname,
     326             :                         int flags)
     327             : {
     328           0 :         struct smb_filename *full_fname = NULL;
     329           0 :         struct smb_filename *smb_fname_tmp = NULL;
     330           0 :         char *cappath = NULL;
     331             :         int ret;
     332             : 
     333           0 :         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     334             :                                                   dirfsp,
     335             :                                                   smb_fname);
     336           0 :         if (full_fname == NULL) {
     337           0 :                 return -1;
     338             :         }
     339             : 
     340           0 :         cappath = capencode(talloc_tos(), full_fname->base_name);
     341           0 :         if (!cappath) {
     342           0 :                 TALLOC_FREE(full_fname);
     343           0 :                 errno = ENOMEM;
     344           0 :                 return -1;
     345             :         }
     346             : 
     347             :         /* Setup temporary smb_filename structs. */
     348           0 :         smb_fname_tmp = cp_smb_filename(talloc_tos(), full_fname);
     349           0 :         TALLOC_FREE(full_fname);
     350           0 :         if (smb_fname_tmp == NULL) {
     351           0 :                 errno = ENOMEM;
     352           0 :                 return -1;
     353             :         }
     354             : 
     355           0 :         smb_fname_tmp->base_name = cappath;
     356             : 
     357           0 :         ret = SMB_VFS_NEXT_UNLINKAT(handle,
     358             :                         dirfsp->conn->cwd_fsp,
     359             :                         smb_fname_tmp,
     360             :                         flags);
     361             : 
     362           0 :         TALLOC_FREE(smb_fname_tmp);
     363           0 :         return ret;
     364             : }
     365             : 
     366           0 : static int cap_lchown(vfs_handle_struct *handle,
     367             :                         const struct smb_filename *smb_fname,
     368             :                         uid_t uid,
     369             :                         gid_t gid)
     370             : {
     371           0 :         struct smb_filename *cap_smb_fname = NULL;
     372           0 :         char *cappath = capencode(talloc_tos(), smb_fname->base_name);
     373             :         int ret;
     374             :         int saved_errno;
     375             : 
     376           0 :         if (!cappath) {
     377           0 :                 errno = ENOMEM;
     378           0 :                 return -1;
     379             :         }
     380             : 
     381           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     382             :                                         cappath,
     383             :                                         NULL,
     384             :                                         NULL,
     385             :                                         smb_fname->twrp,
     386             :                                         smb_fname->flags);
     387           0 :         if (cap_smb_fname == NULL) {
     388           0 :                 TALLOC_FREE(cappath);
     389           0 :                 errno = ENOMEM;
     390           0 :                 return -1;
     391             :         }
     392             : 
     393           0 :         ret = SMB_VFS_NEXT_LCHOWN(handle, cap_smb_fname, uid, gid);
     394           0 :         saved_errno = errno;
     395           0 :         TALLOC_FREE(cappath);
     396           0 :         TALLOC_FREE(cap_smb_fname);
     397           0 :         errno = saved_errno;
     398           0 :         return ret;
     399             : }
     400             : 
     401           0 : static int cap_chdir(vfs_handle_struct *handle,
     402             :                         const struct smb_filename *smb_fname)
     403             : {
     404           0 :         struct smb_filename *cap_smb_fname = NULL;
     405           0 :         char *cappath = capencode(talloc_tos(), smb_fname->base_name);
     406             :         int ret;
     407           0 :         int saved_errno = 0;
     408             : 
     409           0 :         if (!cappath) {
     410           0 :                 errno = ENOMEM;
     411           0 :                 return -1;
     412             :         }
     413           0 :         DEBUG(3,("cap: cap_chdir for %s\n", smb_fname->base_name));
     414             : 
     415           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     416             :                                         cappath,
     417             :                                         NULL,
     418             :                                         NULL,
     419             :                                         smb_fname->twrp,
     420             :                                         smb_fname->flags);
     421           0 :         if (cap_smb_fname == NULL) {
     422           0 :                 TALLOC_FREE(cappath);
     423           0 :                 errno = ENOMEM;
     424           0 :                 return -1;
     425             :         }
     426           0 :         ret = SMB_VFS_NEXT_CHDIR(handle, cap_smb_fname);
     427           0 :         if (ret == -1) {
     428           0 :                 saved_errno = errno;
     429             :         }
     430           0 :         TALLOC_FREE(cappath);
     431           0 :         TALLOC_FREE(cap_smb_fname);
     432           0 :         if (saved_errno != 0) {
     433           0 :                 errno = saved_errno;
     434             :         }
     435           0 :         return ret;
     436             : }
     437             : 
     438           0 : static int cap_symlinkat(vfs_handle_struct *handle,
     439             :                         const struct smb_filename *link_contents,
     440             :                         struct files_struct *dirfsp,
     441             :                         const struct smb_filename *new_smb_fname)
     442             : {
     443           0 :         struct smb_filename *full_fname = NULL;
     444           0 :         char *capold = capencode(talloc_tos(), link_contents->base_name);
     445           0 :         char *capnew = NULL;
     446           0 :         struct smb_filename *new_link_target = NULL;
     447           0 :         struct smb_filename *new_cap_smb_fname = NULL;
     448           0 :         int saved_errno = 0;
     449             :         int ret;
     450             : 
     451           0 :         if (!capold || !capnew) {
     452           0 :                 errno = ENOMEM;
     453           0 :                 return -1;
     454             :         }
     455             : 
     456           0 :         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     457             :                                                 dirfsp,
     458             :                                                 new_smb_fname);
     459           0 :         if (full_fname == NULL) {
     460           0 :                 return -1;
     461             :         }
     462             : 
     463           0 :         capnew = capencode(talloc_tos(), full_fname->base_name);
     464           0 :         if (!capnew) {
     465           0 :                 TALLOC_FREE(full_fname);
     466           0 :                 errno = ENOMEM;
     467           0 :                 return -1;
     468             :         }
     469             : 
     470           0 :         new_link_target = synthetic_smb_fname(talloc_tos(),
     471             :                                               capold,
     472             :                                               NULL,
     473             :                                               NULL,
     474             :                                               new_smb_fname->twrp,
     475             :                                               new_smb_fname->flags);
     476           0 :         if (new_link_target == NULL) {
     477           0 :                 TALLOC_FREE(full_fname);
     478           0 :                 TALLOC_FREE(capold);
     479           0 :                 TALLOC_FREE(capnew);
     480           0 :                 errno = ENOMEM;
     481           0 :                 return -1;
     482             :         }
     483             : 
     484           0 :         new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     485             :                                         capnew,
     486             :                                         NULL,
     487             :                                         NULL,
     488             :                                         new_smb_fname->twrp,
     489             :                                         new_smb_fname->flags);
     490           0 :         if (new_cap_smb_fname == NULL) {
     491           0 :                 TALLOC_FREE(full_fname);
     492           0 :                 TALLOC_FREE(capold);
     493           0 :                 TALLOC_FREE(capnew);
     494           0 :                 TALLOC_FREE(new_link_target);
     495           0 :                 errno = ENOMEM;
     496           0 :                 return -1;
     497             :         }
     498           0 :         ret = SMB_VFS_NEXT_SYMLINKAT(handle,
     499             :                         new_link_target,
     500             :                         handle->conn->cwd_fsp,
     501             :                         new_cap_smb_fname);
     502           0 :         if (ret == -1) {
     503           0 :                 saved_errno = errno;
     504             :         }
     505           0 :         TALLOC_FREE(full_fname);
     506           0 :         TALLOC_FREE(capold);
     507           0 :         TALLOC_FREE(capnew);
     508           0 :         TALLOC_FREE(new_link_target);
     509           0 :         TALLOC_FREE(new_cap_smb_fname);
     510           0 :         if (saved_errno != 0) {
     511           0 :                 errno = saved_errno;
     512             :         }
     513           0 :         return ret;
     514             : }
     515             : 
     516           0 : static int cap_readlinkat(vfs_handle_struct *handle,
     517             :                         const struct files_struct *dirfsp,
     518             :                         const struct smb_filename *smb_fname,
     519             :                         char *buf,
     520             :                         size_t bufsiz)
     521             : {
     522           0 :         struct smb_filename *full_fname = NULL;
     523           0 :         struct smb_filename *cap_smb_fname = NULL;
     524           0 :         char *cappath = NULL;
     525           0 :         int saved_errno = 0;
     526             :         int ret;
     527             : 
     528           0 :         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     529             :                                                 dirfsp,
     530             :                                                 smb_fname);
     531           0 :         if (full_fname == NULL) {
     532           0 :                 return -1;
     533             :         }
     534             : 
     535           0 :         cappath = capencode(talloc_tos(), full_fname->base_name);
     536           0 :         if (cappath == NULL) {
     537           0 :                 TALLOC_FREE(full_fname);
     538           0 :                 errno = ENOMEM;
     539           0 :                 return -1;
     540             :         }
     541           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     542             :                                         cappath,
     543             :                                         NULL,
     544             :                                         NULL,
     545             :                                         smb_fname->twrp,
     546             :                                         smb_fname->flags);
     547           0 :         if (cap_smb_fname == NULL) {
     548           0 :                 TALLOC_FREE(full_fname);
     549           0 :                 TALLOC_FREE(cappath);
     550           0 :                 errno = ENOMEM;
     551           0 :                 return -1;
     552             :         }
     553           0 :         ret = SMB_VFS_NEXT_READLINKAT(handle,
     554             :                         handle->conn->cwd_fsp,
     555             :                         cap_smb_fname,
     556             :                         buf,
     557             :                         bufsiz);
     558           0 :         if (ret == -1) {
     559           0 :                 saved_errno = errno;
     560             :         }
     561           0 :         TALLOC_FREE(full_fname);
     562           0 :         TALLOC_FREE(cappath);
     563           0 :         TALLOC_FREE(cap_smb_fname);
     564           0 :         if (saved_errno != 0) {
     565           0 :                 errno = saved_errno;
     566             :         }
     567           0 :         return ret;
     568             : }
     569             : 
     570           0 : static int cap_linkat(vfs_handle_struct *handle,
     571             :                 files_struct *srcfsp,
     572             :                 const struct smb_filename *old_smb_fname,
     573             :                 files_struct *dstfsp,
     574             :                 const struct smb_filename *new_smb_fname,
     575             :                 int flags)
     576             : {
     577           0 :         struct smb_filename *old_full_fname = NULL;
     578           0 :         struct smb_filename *new_full_fname = NULL;
     579           0 :         char *capold = NULL;
     580           0 :         char *capnew = NULL;
     581           0 :         struct smb_filename *old_cap_smb_fname = NULL;
     582           0 :         struct smb_filename *new_cap_smb_fname = NULL;
     583           0 :         int saved_errno = 0;
     584             :         int ret;
     585             : 
     586             :         /* Process 'old' name. */
     587           0 :         old_full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     588             :                                                 srcfsp,
     589             :                                                 old_smb_fname);
     590           0 :         if (old_full_fname == NULL) {
     591           0 :                 goto nomem_out;
     592             :         }
     593           0 :         capold = capencode(talloc_tos(), old_full_fname->base_name);
     594           0 :         if (capold == NULL) {
     595           0 :                 goto nomem_out;
     596             :         }
     597           0 :         TALLOC_FREE(old_full_fname);
     598           0 :         old_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     599             :                                         capold,
     600             :                                         NULL,
     601             :                                         NULL,
     602             :                                         old_smb_fname->twrp,
     603             :                                         old_smb_fname->flags);
     604           0 :         if (old_cap_smb_fname == NULL) {
     605           0 :                 goto nomem_out;
     606             :         }
     607             : 
     608             :         /* Process 'new' name. */
     609           0 :         new_full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     610             :                                                 dstfsp,
     611             :                                                 new_smb_fname);
     612           0 :         if (new_full_fname == NULL) {
     613           0 :                 goto nomem_out;
     614             :         }
     615           0 :         capnew = capencode(talloc_tos(), new_full_fname->base_name);
     616           0 :         if (capnew == NULL) {
     617           0 :                 goto nomem_out;
     618             :         }
     619           0 :         TALLOC_FREE(new_full_fname);
     620           0 :         new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     621             :                                         capnew,
     622             :                                         NULL,
     623             :                                         NULL,
     624             :                                         new_smb_fname->twrp,
     625             :                                         new_smb_fname->flags);
     626           0 :         if (new_cap_smb_fname == NULL) {
     627           0 :                 goto nomem_out;
     628             :         }
     629             : 
     630           0 :         ret = SMB_VFS_NEXT_LINKAT(handle,
     631             :                         handle->conn->cwd_fsp,
     632             :                         old_cap_smb_fname,
     633             :                         handle->conn->cwd_fsp,
     634             :                         new_cap_smb_fname,
     635             :                         flags);
     636           0 :         if (ret == -1) {
     637           0 :                 saved_errno = errno;
     638             :         }
     639           0 :         TALLOC_FREE(old_full_fname);
     640           0 :         TALLOC_FREE(old_full_fname);
     641           0 :         TALLOC_FREE(capold);
     642           0 :         TALLOC_FREE(capnew);
     643           0 :         TALLOC_FREE(old_cap_smb_fname);
     644           0 :         TALLOC_FREE(new_cap_smb_fname);
     645           0 :         if (saved_errno != 0) {
     646           0 :                 errno = saved_errno;
     647             :         }
     648           0 :         return ret;
     649             : 
     650           0 :   nomem_out:
     651             : 
     652           0 :         TALLOC_FREE(old_full_fname);
     653           0 :         TALLOC_FREE(old_full_fname);
     654           0 :         TALLOC_FREE(capold);
     655           0 :         TALLOC_FREE(capnew);
     656           0 :         TALLOC_FREE(old_cap_smb_fname);
     657           0 :         TALLOC_FREE(new_cap_smb_fname);
     658           0 :         errno = ENOMEM;
     659           0 :         return -1;
     660             : }
     661             : 
     662           0 : static int cap_mknodat(vfs_handle_struct *handle,
     663             :                 files_struct *dirfsp,
     664             :                 const struct smb_filename *smb_fname,
     665             :                 mode_t mode,
     666             :                 SMB_DEV_T dev)
     667             : {
     668           0 :         struct smb_filename *full_fname = NULL;
     669           0 :         struct smb_filename *cap_smb_fname = NULL;
     670           0 :         char *cappath = NULL;
     671             :         int ret;
     672           0 :         int saved_errno = 0;
     673             : 
     674           0 :         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     675             :                                                 dirfsp,
     676             :                                                 smb_fname);
     677           0 :         if (full_fname == NULL) {
     678           0 :                 return -1;
     679             :         }
     680             : 
     681           0 :         cappath = capencode(talloc_tos(), full_fname->base_name);
     682           0 :         if (!cappath) {
     683           0 :                 TALLOC_FREE(full_fname);
     684           0 :                 errno = ENOMEM;
     685           0 :                 return -1;
     686             :         }
     687           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     688             :                                         cappath,
     689             :                                         NULL,
     690             :                                         NULL,
     691             :                                         smb_fname->twrp,
     692             :                                         smb_fname->flags);
     693           0 :         if (cap_smb_fname == NULL) {
     694           0 :                 TALLOC_FREE(full_fname);
     695           0 :                 TALLOC_FREE(cappath);
     696           0 :                 errno = ENOMEM;
     697           0 :                 return -1;
     698             :         }
     699           0 :         ret = SMB_VFS_NEXT_MKNODAT(handle,
     700             :                         handle->conn->cwd_fsp,
     701             :                         cap_smb_fname,
     702             :                         mode,
     703             :                         dev);
     704           0 :         if (ret == -1) {
     705           0 :                 saved_errno = errno;
     706             :         }
     707           0 :         TALLOC_FREE(full_fname);
     708           0 :         TALLOC_FREE(cappath);
     709           0 :         TALLOC_FREE(cap_smb_fname);
     710           0 :         if (saved_errno != 0) {
     711           0 :                 errno = saved_errno;
     712             :         }
     713           0 :         return ret;
     714             : }
     715             : 
     716           0 : static struct smb_filename *cap_realpath(vfs_handle_struct *handle,
     717             :                         TALLOC_CTX *ctx,
     718             :                         const struct smb_filename *smb_fname)
     719             : {
     720             :         /* monyo need capencode'ed and capdecode'ed? */
     721           0 :         struct smb_filename *cap_smb_fname = NULL;
     722           0 :         struct smb_filename *return_fname = NULL;
     723           0 :         char *cappath = capencode(talloc_tos(), smb_fname->base_name);
     724           0 :         int saved_errno = 0;
     725             : 
     726           0 :         if (!cappath) {
     727           0 :                 errno = ENOMEM;
     728           0 :                 return NULL;
     729             :         }
     730           0 :         cap_smb_fname = synthetic_smb_fname(ctx,
     731             :                                         cappath,
     732             :                                         NULL,
     733             :                                         NULL,
     734             :                                         smb_fname->twrp,
     735             :                                         smb_fname->flags);
     736           0 :         if (cap_smb_fname == NULL) {
     737           0 :                 TALLOC_FREE(cappath);
     738           0 :                 errno = ENOMEM;
     739           0 :                 return NULL;
     740             :         }
     741           0 :         return_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, cap_smb_fname);
     742           0 :         if (return_fname == NULL) {
     743           0 :                 saved_errno = errno;
     744             :         }
     745           0 :         TALLOC_FREE(cappath);
     746           0 :         TALLOC_FREE(cap_smb_fname);
     747           0 :         if (saved_errno != 0) {
     748           0 :                 errno = saved_errno;
     749             :         }
     750           0 :         return return_fname;
     751             : }
     752             : 
     753           0 : static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, void *value, size_t size)
     754             : {
     755           0 :         char *cappath = capencode(talloc_tos(), path);
     756             : 
     757           0 :         if (!cappath) {
     758           0 :                 errno = ENOMEM;
     759           0 :                 return -1;
     760             :         }
     761           0 :         return SMB_VFS_NEXT_FGETXATTR(handle, fsp, cappath, value, size);
     762             : }
     763             : 
     764           0 : static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path)
     765             : {
     766           0 :         char *cappath = capencode(talloc_tos(), path);
     767             : 
     768           0 :         if (!cappath) {
     769           0 :                 errno = ENOMEM;
     770           0 :                 return -1;
     771             :         }
     772           0 :         return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, cappath);
     773             : }
     774             : 
     775           0 : static int cap_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, const void *value, size_t size, int flags)
     776             : {
     777           0 :         char *cappath = capencode(talloc_tos(), path);
     778             : 
     779           0 :         if (!cappath) {
     780           0 :                 errno = ENOMEM;
     781           0 :                 return -1;
     782             :         }
     783           0 :         return SMB_VFS_NEXT_FSETXATTR(handle, fsp, cappath, value, size, flags);
     784             : }
     785             : 
     786           0 : static NTSTATUS cap_create_dfs_pathat(vfs_handle_struct *handle,
     787             :                         files_struct *dirfsp,
     788             :                         const struct smb_filename *smb_fname,
     789             :                         const struct referral *reflist,
     790             :                         size_t referral_count)
     791             : {
     792           0 :         char *cappath = capencode(talloc_tos(), smb_fname->base_name);
     793           0 :         struct smb_filename *cap_smb_fname = NULL;
     794             :         NTSTATUS status;
     795             : 
     796           0 :         if (cappath == NULL) {
     797           0 :                 return NT_STATUS_NO_MEMORY;
     798             :         }
     799           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     800             :                                         cappath,
     801             :                                         NULL,
     802             :                                         NULL,
     803             :                                         smb_fname->twrp,
     804             :                                         smb_fname->flags);
     805           0 :         if (cap_smb_fname == NULL) {
     806           0 :                 TALLOC_FREE(cappath);
     807           0 :                 return NT_STATUS_NO_MEMORY;
     808             :         }
     809           0 :         status = SMB_VFS_NEXT_CREATE_DFS_PATHAT(handle,
     810             :                         dirfsp,
     811             :                         cap_smb_fname,
     812             :                         reflist,
     813             :                         referral_count);
     814           0 :         TALLOC_FREE(cappath);
     815           0 :         TALLOC_FREE(cap_smb_fname);
     816           0 :         return status;
     817             : }
     818             : 
     819           0 : static NTSTATUS cap_read_dfs_pathat(struct vfs_handle_struct *handle,
     820             :                         TALLOC_CTX *mem_ctx,
     821             :                         struct files_struct *dirfsp,
     822             :                         struct smb_filename *smb_fname,
     823             :                         struct referral **ppreflist,
     824             :                         size_t *preferral_count)
     825             : {
     826           0 :         struct smb_filename *full_fname = NULL;
     827           0 :         struct smb_filename *cap_smb_fname = NULL;
     828           0 :         char *cappath = NULL;
     829             :         NTSTATUS status;
     830             : 
     831           0 :         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     832             :                                                 dirfsp,
     833             :                                                 smb_fname);
     834           0 :         if (full_fname == NULL) {
     835           0 :                 return NT_STATUS_NO_MEMORY;
     836             :         }
     837           0 :         cappath = capencode(talloc_tos(), full_fname->base_name);
     838           0 :         if (cappath == NULL) {
     839           0 :                 TALLOC_FREE(full_fname);
     840           0 :                 return NT_STATUS_NO_MEMORY;
     841             :         }
     842           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     843             :                                 cappath,
     844             :                                 NULL,
     845             :                                 NULL,
     846             :                                 smb_fname->twrp,
     847             :                                 smb_fname->flags);
     848           0 :         if (cap_smb_fname == NULL) {
     849           0 :                 TALLOC_FREE(full_fname);
     850           0 :                 TALLOC_FREE(cappath);
     851           0 :                 return NT_STATUS_NO_MEMORY;
     852             :         }
     853             : 
     854           0 :         status = SMB_VFS_NEXT_READ_DFS_PATHAT(handle,
     855             :                         mem_ctx,
     856             :                         handle->conn->cwd_fsp,
     857             :                         cap_smb_fname,
     858             :                         ppreflist,
     859             :                         preferral_count);
     860             : 
     861           0 :         if (NT_STATUS_IS_OK(status)) {
     862             :                 /* Return any stat(2) info. */
     863           0 :                 smb_fname->st = cap_smb_fname->st;
     864             :         }
     865             : 
     866           0 :         TALLOC_FREE(full_fname);
     867           0 :         TALLOC_FREE(cappath);
     868           0 :         TALLOC_FREE(cap_smb_fname);
     869           0 :         return status;
     870             : }
     871             : 
     872             : static struct vfs_fn_pointers vfs_cap_fns = {
     873             :         .disk_free_fn = cap_disk_free,
     874             :         .get_quota_fn = cap_get_quota,
     875             :         .readdir_fn = cap_readdir,
     876             :         .mkdirat_fn = cap_mkdirat,
     877             :         .openat_fn = cap_openat,
     878             :         .renameat_fn = cap_renameat,
     879             :         .stat_fn = cap_stat,
     880             :         .lstat_fn = cap_lstat,
     881             :         .unlinkat_fn = cap_unlinkat,
     882             :         .lchown_fn = cap_lchown,
     883             :         .chdir_fn = cap_chdir,
     884             :         .symlinkat_fn = cap_symlinkat,
     885             :         .readlinkat_fn = cap_readlinkat,
     886             :         .linkat_fn = cap_linkat,
     887             :         .mknodat_fn = cap_mknodat,
     888             :         .realpath_fn = cap_realpath,
     889             :         .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
     890             :         .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
     891             :         .fgetxattr_fn = cap_fgetxattr,
     892             :         .fremovexattr_fn = cap_fremovexattr,
     893             :         .fsetxattr_fn = cap_fsetxattr,
     894             :         .create_dfs_pathat_fn = cap_create_dfs_pathat,
     895             :         .read_dfs_pathat_fn = cap_read_dfs_pathat
     896             : };
     897             : 
     898             : static_decl_vfs;
     899          20 : NTSTATUS vfs_cap_init(TALLOC_CTX *ctx)
     900             : {
     901          20 :         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "cap",
     902             :                                 &vfs_cap_fns);
     903             : }
     904             : 
     905             : /* For CAP functions */
     906             : #define hex_tag ':'
     907             : #define hex2bin(c)              hex2bin_table[(unsigned char)(c)]
     908             : #define bin2hex(c)              bin2hex_table[(unsigned char)(c)]
     909             : #define is_hex(s)               ((s)[0] == hex_tag)
     910             : 
     911             : static unsigned char hex2bin_table[256] = {
     912             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
     913             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
     914             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
     915             : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
     916             : 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x40 */
     917             : 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
     918             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
     919             : 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x60 */
     920             : 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
     921             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 */
     922             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 */
     923             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 */
     924             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 */
     925             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 */
     926             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 */
     927             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 */
     928             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 */
     929             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  /* 0xf0 */
     930             : };
     931             : static unsigned char bin2hex_table[256] = "0123456789abcdef";
     932             : 
     933             : /*******************************************************************
     934             :   original code -> ":xx"  - CAP format
     935             : ********************************************************************/
     936             : 
     937           0 : static char *capencode(TALLOC_CTX *ctx, const char *from)
     938             : {
     939           0 :         char *out = NULL;
     940             :         const char *p1;
     941           0 :         char *to = NULL;
     942           0 :         size_t len = 0;
     943             : 
     944           0 :         for (p1 = from; *p1; p1++) {
     945           0 :                 if ((unsigned char)*p1 >= 0x80) {
     946           0 :                         len += 3;
     947             :                 } else {
     948           0 :                         len++;
     949             :                 }
     950             :         }
     951           0 :         len++;
     952             : 
     953           0 :         to = talloc_array(ctx, char, len);
     954           0 :         if (!to) {
     955           0 :                 return NULL;
     956             :         }
     957             : 
     958           0 :         for (out = to; *from;) {
     959             :                 /* buffer husoku error */
     960           0 :                 if ((unsigned char)*from >= 0x80) {
     961           0 :                         *out++ = hex_tag;
     962           0 :                         *out++ = bin2hex (((*from)>>4)&0x0f);
     963           0 :                         *out++ = bin2hex ((*from)&0x0f);
     964           0 :                         from++;
     965             :                 } else {
     966           0 :                         *out++ = *from++;
     967             :                 }
     968             :         }
     969           0 :         *out = '\0';
     970           0 :         return to;
     971             : }
     972             : 
     973             : /*******************************************************************
     974             :   CAP -> original code
     975             : ********************************************************************/
     976             : /* ":xx" -> a byte */
     977             : 
     978           0 : static char *capdecode(TALLOC_CTX *ctx, const char *from)
     979             : {
     980             :         const char *p1;
     981           0 :         char *out = NULL;
     982           0 :         char *to = NULL;
     983           0 :         size_t len = 0;
     984             : 
     985           0 :         for (p1 = from; *p1; len++) {
     986           0 :                 if (is_hex(p1)) {
     987           0 :                         p1 += 3;
     988             :                 } else {
     989           0 :                         p1++;
     990             :                 }
     991             :         }
     992           0 :         len++;
     993             : 
     994           0 :         to = talloc_array(ctx, char, len);
     995           0 :         if (!to) {
     996           0 :                 return NULL;
     997             :         }
     998             : 
     999           0 :         for (out = to; *from;) {
    1000           0 :                 if (is_hex(from)) {
    1001           0 :                         *out++ = (hex2bin(from[1])<<4) | (hex2bin(from[2]));
    1002           0 :                         from += 3;
    1003             :                 } else {
    1004           0 :                         *out++ = *from++;
    1005             :                 }
    1006             :         }
    1007           0 :         *out = '\0';
    1008           0 :         return to;
    1009             : }

Generated by: LCOV version 1.13