LCOV - code coverage report
Current view: top level - source3/modules - vfs_cap.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 2 470 0.4 %
Date: 2024-06-13 04:01:37 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             :                       const struct vfs_open_how *how)
     156             : {
     157           0 :         char *cappath = NULL;
     158           0 :         struct smb_filename *smb_fname = NULL;
     159             :         int ret;
     160           0 :         int saved_errno = 0;
     161             : 
     162           0 :         cappath = capencode(talloc_tos(), smb_fname_in->base_name);
     163           0 :         if (cappath == NULL) {
     164           0 :                 errno = ENOMEM;
     165           0 :                 return -1;
     166             :         }
     167             : 
     168           0 :         smb_fname = cp_smb_filename(talloc_tos(), smb_fname_in);
     169           0 :         if (smb_fname == NULL) {
     170           0 :                 TALLOC_FREE(cappath);
     171           0 :                 errno = ENOMEM;
     172           0 :                 return -1;
     173             :         }
     174           0 :         smb_fname->base_name = cappath;
     175             : 
     176           0 :         DBG_DEBUG("cap_open for %s\n", smb_fname_str_dbg(smb_fname));
     177           0 :         ret = SMB_VFS_NEXT_OPENAT(handle,
     178             :                                   dirfsp,
     179             :                                   smb_fname,
     180             :                                   fsp,
     181             :                                   how);
     182           0 :         if (ret == -1) {
     183           0 :                 saved_errno = errno;
     184             :         }
     185           0 :         TALLOC_FREE(cappath);
     186           0 :         TALLOC_FREE(smb_fname);
     187           0 :         if (saved_errno != 0) {
     188           0 :                 errno = saved_errno;
     189             :         }
     190           0 :         return ret;
     191             : }
     192             : 
     193           0 : static int cap_renameat(vfs_handle_struct *handle,
     194             :                         files_struct *srcfsp,
     195             :                         const struct smb_filename *smb_fname_src,
     196             :                         files_struct *dstfsp,
     197             :                         const struct smb_filename *smb_fname_dst)
     198             : {
     199           0 :         char *capold = NULL;
     200           0 :         char *capnew = NULL;
     201           0 :         struct smb_filename *smb_fname_src_tmp = NULL;
     202           0 :         struct smb_filename *smb_fname_dst_tmp = NULL;
     203           0 :         struct smb_filename *full_fname_src = NULL;
     204           0 :         struct smb_filename *full_fname_dst = NULL;
     205           0 :         int ret = -1;
     206           0 :         int saved_errno = 0;
     207             : 
     208           0 :         full_fname_src = full_path_from_dirfsp_atname(talloc_tos(),
     209             :                                                   srcfsp,
     210             :                                                   smb_fname_src);
     211           0 :         if (full_fname_src == NULL) {
     212           0 :                 errno = ENOMEM;
     213           0 :                 goto out;
     214             :         }
     215             : 
     216           0 :         full_fname_dst = full_path_from_dirfsp_atname(talloc_tos(),
     217             :                                                   dstfsp,
     218             :                                                   smb_fname_dst);
     219           0 :         if (full_fname_dst == NULL) {
     220           0 :                 errno = ENOMEM;
     221           0 :                 goto out;
     222             :         }
     223             : 
     224           0 :         capold = capencode(talloc_tos(), full_fname_src->base_name);
     225           0 :         capnew = capencode(talloc_tos(), full_fname_dst->base_name);
     226           0 :         if (!capold || !capnew) {
     227           0 :                 errno = ENOMEM;
     228           0 :                 goto out;
     229             :         }
     230             : 
     231             :         /* Setup temporary smb_filename structs. */
     232           0 :         smb_fname_src_tmp = cp_smb_filename(talloc_tos(), full_fname_src);
     233           0 :         if (smb_fname_src_tmp == NULL) {
     234           0 :                 errno = ENOMEM;
     235           0 :                 goto out;
     236             :         }
     237           0 :         smb_fname_dst_tmp = cp_smb_filename(talloc_tos(), full_fname_dst);
     238           0 :         if (smb_fname_dst_tmp == NULL) {
     239           0 :                 errno = ENOMEM;
     240           0 :                 goto out;
     241             :         }
     242             : 
     243           0 :         smb_fname_src_tmp->base_name = capold;
     244           0 :         smb_fname_dst_tmp->base_name = capnew;
     245             : 
     246           0 :         ret = SMB_VFS_NEXT_RENAMEAT(handle,
     247             :                                 srcfsp->conn->cwd_fsp,
     248             :                                 smb_fname_src_tmp,
     249             :                                 dstfsp->conn->cwd_fsp,
     250             :                                 smb_fname_dst_tmp);
     251             : 
     252           0 :  out:
     253             : 
     254           0 :         if (ret != 0) {
     255           0 :                 saved_errno = errno;
     256             :         }
     257             : 
     258           0 :         TALLOC_FREE(full_fname_src);
     259           0 :         TALLOC_FREE(full_fname_dst);
     260           0 :         TALLOC_FREE(capold);
     261           0 :         TALLOC_FREE(capnew);
     262           0 :         TALLOC_FREE(smb_fname_src_tmp);
     263           0 :         TALLOC_FREE(smb_fname_dst_tmp);
     264             : 
     265           0 :         if (ret != 0) {
     266           0 :                 errno = saved_errno;
     267             :         }
     268             : 
     269           0 :         return ret;
     270             : }
     271             : 
     272           0 : static int cap_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
     273             : {
     274             :         char *cappath;
     275           0 :         char *tmp_base_name = NULL;
     276             :         int ret;
     277             : 
     278           0 :         cappath = capencode(talloc_tos(), smb_fname->base_name);
     279             : 
     280           0 :         if (!cappath) {
     281           0 :                 errno = ENOMEM;
     282           0 :                 return -1;
     283             :         }
     284             : 
     285           0 :         tmp_base_name = smb_fname->base_name;
     286           0 :         smb_fname->base_name = cappath;
     287             : 
     288           0 :         ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
     289             : 
     290           0 :         smb_fname->base_name = tmp_base_name;
     291           0 :         TALLOC_FREE(cappath);
     292             : 
     293           0 :         return ret;
     294             : }
     295             : 
     296           0 : static int cap_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
     297             : {
     298             :         char *cappath;
     299           0 :         char *tmp_base_name = NULL;
     300             :         int ret;
     301             : 
     302           0 :         cappath = capencode(talloc_tos(), smb_fname->base_name);
     303             : 
     304           0 :         if (!cappath) {
     305           0 :                 errno = ENOMEM;
     306           0 :                 return -1;
     307             :         }
     308             : 
     309           0 :         tmp_base_name = smb_fname->base_name;
     310           0 :         smb_fname->base_name = cappath;
     311             : 
     312           0 :         ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
     313             : 
     314           0 :         smb_fname->base_name = tmp_base_name;
     315           0 :         TALLOC_FREE(cappath);
     316             : 
     317           0 :         return ret;
     318             : }
     319             : 
     320           0 : static int cap_unlinkat(vfs_handle_struct *handle,
     321             :                         struct files_struct *dirfsp,
     322             :                         const struct smb_filename *smb_fname,
     323             :                         int flags)
     324             : {
     325           0 :         struct smb_filename *full_fname = NULL;
     326           0 :         struct smb_filename *smb_fname_tmp = NULL;
     327           0 :         char *cappath = NULL;
     328             :         int ret;
     329             : 
     330           0 :         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     331             :                                                   dirfsp,
     332             :                                                   smb_fname);
     333           0 :         if (full_fname == NULL) {
     334           0 :                 return -1;
     335             :         }
     336             : 
     337           0 :         cappath = capencode(talloc_tos(), full_fname->base_name);
     338           0 :         if (!cappath) {
     339           0 :                 TALLOC_FREE(full_fname);
     340           0 :                 errno = ENOMEM;
     341           0 :                 return -1;
     342             :         }
     343             : 
     344             :         /* Setup temporary smb_filename structs. */
     345           0 :         smb_fname_tmp = cp_smb_filename(talloc_tos(), full_fname);
     346           0 :         TALLOC_FREE(full_fname);
     347           0 :         if (smb_fname_tmp == NULL) {
     348           0 :                 errno = ENOMEM;
     349           0 :                 return -1;
     350             :         }
     351             : 
     352           0 :         smb_fname_tmp->base_name = cappath;
     353             : 
     354           0 :         ret = SMB_VFS_NEXT_UNLINKAT(handle,
     355             :                         dirfsp->conn->cwd_fsp,
     356             :                         smb_fname_tmp,
     357             :                         flags);
     358             : 
     359           0 :         TALLOC_FREE(smb_fname_tmp);
     360           0 :         return ret;
     361             : }
     362             : 
     363           0 : static int cap_lchown(vfs_handle_struct *handle,
     364             :                         const struct smb_filename *smb_fname,
     365             :                         uid_t uid,
     366             :                         gid_t gid)
     367             : {
     368           0 :         struct smb_filename *cap_smb_fname = NULL;
     369           0 :         char *cappath = capencode(talloc_tos(), smb_fname->base_name);
     370             :         int ret;
     371             :         int saved_errno;
     372             : 
     373           0 :         if (!cappath) {
     374           0 :                 errno = ENOMEM;
     375           0 :                 return -1;
     376             :         }
     377             : 
     378           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     379             :                                         cappath,
     380             :                                         NULL,
     381             :                                         NULL,
     382             :                                         smb_fname->twrp,
     383             :                                         smb_fname->flags);
     384           0 :         if (cap_smb_fname == NULL) {
     385           0 :                 TALLOC_FREE(cappath);
     386           0 :                 errno = ENOMEM;
     387           0 :                 return -1;
     388             :         }
     389             : 
     390           0 :         ret = SMB_VFS_NEXT_LCHOWN(handle, cap_smb_fname, uid, gid);
     391           0 :         saved_errno = errno;
     392           0 :         TALLOC_FREE(cappath);
     393           0 :         TALLOC_FREE(cap_smb_fname);
     394           0 :         errno = saved_errno;
     395           0 :         return ret;
     396             : }
     397             : 
     398           0 : static int cap_chdir(vfs_handle_struct *handle,
     399             :                         const struct smb_filename *smb_fname)
     400             : {
     401           0 :         struct smb_filename *cap_smb_fname = NULL;
     402           0 :         char *cappath = capencode(talloc_tos(), smb_fname->base_name);
     403             :         int ret;
     404           0 :         int saved_errno = 0;
     405             : 
     406           0 :         if (!cappath) {
     407           0 :                 errno = ENOMEM;
     408           0 :                 return -1;
     409             :         }
     410           0 :         DEBUG(3,("cap: cap_chdir for %s\n", smb_fname->base_name));
     411             : 
     412           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     413             :                                         cappath,
     414             :                                         NULL,
     415             :                                         NULL,
     416             :                                         smb_fname->twrp,
     417             :                                         smb_fname->flags);
     418           0 :         if (cap_smb_fname == NULL) {
     419           0 :                 TALLOC_FREE(cappath);
     420           0 :                 errno = ENOMEM;
     421           0 :                 return -1;
     422             :         }
     423           0 :         ret = SMB_VFS_NEXT_CHDIR(handle, cap_smb_fname);
     424           0 :         if (ret == -1) {
     425           0 :                 saved_errno = errno;
     426             :         }
     427           0 :         TALLOC_FREE(cappath);
     428           0 :         TALLOC_FREE(cap_smb_fname);
     429           0 :         if (saved_errno != 0) {
     430           0 :                 errno = saved_errno;
     431             :         }
     432           0 :         return ret;
     433             : }
     434             : 
     435           0 : static int cap_symlinkat(vfs_handle_struct *handle,
     436             :                         const struct smb_filename *link_contents,
     437             :                         struct files_struct *dirfsp,
     438             :                         const struct smb_filename *new_smb_fname)
     439             : {
     440           0 :         struct smb_filename *full_fname = NULL;
     441           0 :         char *capold = capencode(talloc_tos(), link_contents->base_name);
     442           0 :         char *capnew = NULL;
     443           0 :         struct smb_filename *new_link_target = NULL;
     444           0 :         struct smb_filename *new_cap_smb_fname = NULL;
     445           0 :         int saved_errno = 0;
     446             :         int ret;
     447             : 
     448           0 :         if (capold == NULL) {
     449           0 :                 errno = ENOMEM;
     450           0 :                 return -1;
     451             :         }
     452             : 
     453           0 :         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     454             :                                                 dirfsp,
     455             :                                                 new_smb_fname);
     456           0 :         if (full_fname == NULL) {
     457           0 :                 return -1;
     458             :         }
     459             : 
     460           0 :         capnew = capencode(talloc_tos(), full_fname->base_name);
     461           0 :         if (!capnew) {
     462           0 :                 TALLOC_FREE(full_fname);
     463           0 :                 errno = ENOMEM;
     464           0 :                 return -1;
     465             :         }
     466             : 
     467           0 :         new_link_target = synthetic_smb_fname(talloc_tos(),
     468             :                                               capold,
     469             :                                               NULL,
     470             :                                               NULL,
     471             :                                               new_smb_fname->twrp,
     472             :                                               new_smb_fname->flags);
     473           0 :         if (new_link_target == NULL) {
     474           0 :                 TALLOC_FREE(full_fname);
     475           0 :                 TALLOC_FREE(capold);
     476           0 :                 TALLOC_FREE(capnew);
     477           0 :                 errno = ENOMEM;
     478           0 :                 return -1;
     479             :         }
     480             : 
     481           0 :         new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     482             :                                         capnew,
     483             :                                         NULL,
     484             :                                         NULL,
     485             :                                         new_smb_fname->twrp,
     486             :                                         new_smb_fname->flags);
     487           0 :         if (new_cap_smb_fname == NULL) {
     488           0 :                 TALLOC_FREE(full_fname);
     489           0 :                 TALLOC_FREE(capold);
     490           0 :                 TALLOC_FREE(capnew);
     491           0 :                 TALLOC_FREE(new_link_target);
     492           0 :                 errno = ENOMEM;
     493           0 :                 return -1;
     494             :         }
     495           0 :         ret = SMB_VFS_NEXT_SYMLINKAT(handle,
     496             :                         new_link_target,
     497             :                         handle->conn->cwd_fsp,
     498             :                         new_cap_smb_fname);
     499           0 :         if (ret == -1) {
     500           0 :                 saved_errno = errno;
     501             :         }
     502           0 :         TALLOC_FREE(full_fname);
     503           0 :         TALLOC_FREE(capold);
     504           0 :         TALLOC_FREE(capnew);
     505           0 :         TALLOC_FREE(new_link_target);
     506           0 :         TALLOC_FREE(new_cap_smb_fname);
     507           0 :         if (saved_errno != 0) {
     508           0 :                 errno = saved_errno;
     509             :         }
     510           0 :         return ret;
     511             : }
     512             : 
     513           0 : static int cap_readlinkat(vfs_handle_struct *handle,
     514             :                         const struct files_struct *dirfsp,
     515             :                         const struct smb_filename *smb_fname,
     516             :                         char *buf,
     517             :                         size_t bufsiz)
     518             : {
     519           0 :         struct smb_filename *full_fname = NULL;
     520           0 :         struct smb_filename *cap_smb_fname = NULL;
     521           0 :         char *cappath = NULL;
     522           0 :         int saved_errno = 0;
     523             :         int ret;
     524             : 
     525           0 :         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     526             :                                                 dirfsp,
     527             :                                                 smb_fname);
     528           0 :         if (full_fname == NULL) {
     529           0 :                 return -1;
     530             :         }
     531             : 
     532           0 :         cappath = capencode(talloc_tos(), full_fname->base_name);
     533           0 :         if (cappath == NULL) {
     534           0 :                 TALLOC_FREE(full_fname);
     535           0 :                 errno = ENOMEM;
     536           0 :                 return -1;
     537             :         }
     538           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     539             :                                         cappath,
     540             :                                         NULL,
     541             :                                         NULL,
     542             :                                         smb_fname->twrp,
     543             :                                         smb_fname->flags);
     544           0 :         if (cap_smb_fname == NULL) {
     545           0 :                 TALLOC_FREE(full_fname);
     546           0 :                 TALLOC_FREE(cappath);
     547           0 :                 errno = ENOMEM;
     548           0 :                 return -1;
     549             :         }
     550           0 :         ret = SMB_VFS_NEXT_READLINKAT(handle,
     551             :                         handle->conn->cwd_fsp,
     552             :                         cap_smb_fname,
     553             :                         buf,
     554             :                         bufsiz);
     555           0 :         if (ret == -1) {
     556           0 :                 saved_errno = errno;
     557             :         }
     558           0 :         TALLOC_FREE(full_fname);
     559           0 :         TALLOC_FREE(cappath);
     560           0 :         TALLOC_FREE(cap_smb_fname);
     561           0 :         if (saved_errno != 0) {
     562           0 :                 errno = saved_errno;
     563             :         }
     564           0 :         return ret;
     565             : }
     566             : 
     567           0 : static int cap_linkat(vfs_handle_struct *handle,
     568             :                 files_struct *srcfsp,
     569             :                 const struct smb_filename *old_smb_fname,
     570             :                 files_struct *dstfsp,
     571             :                 const struct smb_filename *new_smb_fname,
     572             :                 int flags)
     573             : {
     574           0 :         struct smb_filename *old_full_fname = NULL;
     575           0 :         struct smb_filename *new_full_fname = NULL;
     576           0 :         char *capold = NULL;
     577           0 :         char *capnew = NULL;
     578           0 :         struct smb_filename *old_cap_smb_fname = NULL;
     579           0 :         struct smb_filename *new_cap_smb_fname = NULL;
     580           0 :         int saved_errno = 0;
     581             :         int ret;
     582             : 
     583             :         /* Process 'old' name. */
     584           0 :         old_full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     585             :                                                 srcfsp,
     586             :                                                 old_smb_fname);
     587           0 :         if (old_full_fname == NULL) {
     588           0 :                 goto nomem_out;
     589             :         }
     590           0 :         capold = capencode(talloc_tos(), old_full_fname->base_name);
     591           0 :         if (capold == NULL) {
     592           0 :                 goto nomem_out;
     593             :         }
     594           0 :         TALLOC_FREE(old_full_fname);
     595           0 :         old_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     596             :                                         capold,
     597             :                                         NULL,
     598             :                                         NULL,
     599             :                                         old_smb_fname->twrp,
     600             :                                         old_smb_fname->flags);
     601           0 :         if (old_cap_smb_fname == NULL) {
     602           0 :                 goto nomem_out;
     603             :         }
     604             : 
     605             :         /* Process 'new' name. */
     606           0 :         new_full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     607             :                                                 dstfsp,
     608             :                                                 new_smb_fname);
     609           0 :         if (new_full_fname == NULL) {
     610           0 :                 goto nomem_out;
     611             :         }
     612           0 :         capnew = capencode(talloc_tos(), new_full_fname->base_name);
     613           0 :         if (capnew == NULL) {
     614           0 :                 goto nomem_out;
     615             :         }
     616           0 :         TALLOC_FREE(new_full_fname);
     617           0 :         new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     618             :                                         capnew,
     619             :                                         NULL,
     620             :                                         NULL,
     621             :                                         new_smb_fname->twrp,
     622             :                                         new_smb_fname->flags);
     623           0 :         if (new_cap_smb_fname == NULL) {
     624           0 :                 goto nomem_out;
     625             :         }
     626             : 
     627           0 :         ret = SMB_VFS_NEXT_LINKAT(handle,
     628             :                         handle->conn->cwd_fsp,
     629             :                         old_cap_smb_fname,
     630             :                         handle->conn->cwd_fsp,
     631             :                         new_cap_smb_fname,
     632             :                         flags);
     633           0 :         if (ret == -1) {
     634           0 :                 saved_errno = errno;
     635             :         }
     636           0 :         TALLOC_FREE(old_full_fname);
     637           0 :         TALLOC_FREE(old_full_fname);
     638           0 :         TALLOC_FREE(capold);
     639           0 :         TALLOC_FREE(capnew);
     640           0 :         TALLOC_FREE(old_cap_smb_fname);
     641           0 :         TALLOC_FREE(new_cap_smb_fname);
     642           0 :         if (saved_errno != 0) {
     643           0 :                 errno = saved_errno;
     644             :         }
     645           0 :         return ret;
     646             : 
     647           0 :   nomem_out:
     648             : 
     649           0 :         TALLOC_FREE(old_full_fname);
     650           0 :         TALLOC_FREE(old_full_fname);
     651           0 :         TALLOC_FREE(capold);
     652           0 :         TALLOC_FREE(capnew);
     653           0 :         TALLOC_FREE(old_cap_smb_fname);
     654           0 :         TALLOC_FREE(new_cap_smb_fname);
     655           0 :         errno = ENOMEM;
     656           0 :         return -1;
     657             : }
     658             : 
     659           0 : static int cap_mknodat(vfs_handle_struct *handle,
     660             :                 files_struct *dirfsp,
     661             :                 const struct smb_filename *smb_fname,
     662             :                 mode_t mode,
     663             :                 SMB_DEV_T dev)
     664             : {
     665           0 :         struct smb_filename *full_fname = NULL;
     666           0 :         struct smb_filename *cap_smb_fname = NULL;
     667           0 :         char *cappath = NULL;
     668             :         int ret;
     669           0 :         int saved_errno = 0;
     670             : 
     671           0 :         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     672             :                                                 dirfsp,
     673             :                                                 smb_fname);
     674           0 :         if (full_fname == NULL) {
     675           0 :                 return -1;
     676             :         }
     677             : 
     678           0 :         cappath = capencode(talloc_tos(), full_fname->base_name);
     679           0 :         if (!cappath) {
     680           0 :                 TALLOC_FREE(full_fname);
     681           0 :                 errno = ENOMEM;
     682           0 :                 return -1;
     683             :         }
     684           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     685             :                                         cappath,
     686             :                                         NULL,
     687             :                                         NULL,
     688             :                                         smb_fname->twrp,
     689             :                                         smb_fname->flags);
     690           0 :         if (cap_smb_fname == NULL) {
     691           0 :                 TALLOC_FREE(full_fname);
     692           0 :                 TALLOC_FREE(cappath);
     693           0 :                 errno = ENOMEM;
     694           0 :                 return -1;
     695             :         }
     696           0 :         ret = SMB_VFS_NEXT_MKNODAT(handle,
     697             :                         handle->conn->cwd_fsp,
     698             :                         cap_smb_fname,
     699             :                         mode,
     700             :                         dev);
     701           0 :         if (ret == -1) {
     702           0 :                 saved_errno = errno;
     703             :         }
     704           0 :         TALLOC_FREE(full_fname);
     705           0 :         TALLOC_FREE(cappath);
     706           0 :         TALLOC_FREE(cap_smb_fname);
     707           0 :         if (saved_errno != 0) {
     708           0 :                 errno = saved_errno;
     709             :         }
     710           0 :         return ret;
     711             : }
     712             : 
     713           0 : static struct smb_filename *cap_realpath(vfs_handle_struct *handle,
     714             :                         TALLOC_CTX *ctx,
     715             :                         const struct smb_filename *smb_fname)
     716             : {
     717             :         /* monyo need capencode'ed and capdecode'ed? */
     718           0 :         struct smb_filename *cap_smb_fname = NULL;
     719           0 :         struct smb_filename *return_fname = NULL;
     720           0 :         char *cappath = capencode(talloc_tos(), smb_fname->base_name);
     721           0 :         int saved_errno = 0;
     722             : 
     723           0 :         if (!cappath) {
     724           0 :                 errno = ENOMEM;
     725           0 :                 return NULL;
     726             :         }
     727           0 :         cap_smb_fname = synthetic_smb_fname(ctx,
     728             :                                         cappath,
     729             :                                         NULL,
     730             :                                         NULL,
     731             :                                         smb_fname->twrp,
     732             :                                         smb_fname->flags);
     733           0 :         if (cap_smb_fname == NULL) {
     734           0 :                 TALLOC_FREE(cappath);
     735           0 :                 errno = ENOMEM;
     736           0 :                 return NULL;
     737             :         }
     738           0 :         return_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, cap_smb_fname);
     739           0 :         if (return_fname == NULL) {
     740           0 :                 saved_errno = errno;
     741             :         }
     742           0 :         TALLOC_FREE(cappath);
     743           0 :         TALLOC_FREE(cap_smb_fname);
     744           0 :         if (saved_errno != 0) {
     745           0 :                 errno = saved_errno;
     746             :         }
     747           0 :         return return_fname;
     748             : }
     749             : 
     750           0 : static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, void *value, size_t size)
     751             : {
     752           0 :         char *cappath = capencode(talloc_tos(), path);
     753             : 
     754           0 :         if (!cappath) {
     755           0 :                 errno = ENOMEM;
     756           0 :                 return -1;
     757             :         }
     758           0 :         return SMB_VFS_NEXT_FGETXATTR(handle, fsp, cappath, value, size);
     759             : }
     760             : 
     761           0 : static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path)
     762             : {
     763           0 :         char *cappath = capencode(talloc_tos(), path);
     764             : 
     765           0 :         if (!cappath) {
     766           0 :                 errno = ENOMEM;
     767           0 :                 return -1;
     768             :         }
     769           0 :         return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, cappath);
     770             : }
     771             : 
     772           0 : static int cap_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, const void *value, size_t size, int flags)
     773             : {
     774           0 :         char *cappath = capencode(talloc_tos(), path);
     775             : 
     776           0 :         if (!cappath) {
     777           0 :                 errno = ENOMEM;
     778           0 :                 return -1;
     779             :         }
     780           0 :         return SMB_VFS_NEXT_FSETXATTR(handle, fsp, cappath, value, size, flags);
     781             : }
     782             : 
     783           0 : static NTSTATUS cap_create_dfs_pathat(vfs_handle_struct *handle,
     784             :                         files_struct *dirfsp,
     785             :                         const struct smb_filename *smb_fname,
     786             :                         const struct referral *reflist,
     787             :                         size_t referral_count)
     788             : {
     789           0 :         char *cappath = capencode(talloc_tos(), smb_fname->base_name);
     790           0 :         struct smb_filename *cap_smb_fname = NULL;
     791             :         NTSTATUS status;
     792             : 
     793           0 :         if (cappath == NULL) {
     794           0 :                 return NT_STATUS_NO_MEMORY;
     795             :         }
     796           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     797             :                                         cappath,
     798             :                                         NULL,
     799             :                                         NULL,
     800             :                                         smb_fname->twrp,
     801             :                                         smb_fname->flags);
     802           0 :         if (cap_smb_fname == NULL) {
     803           0 :                 TALLOC_FREE(cappath);
     804           0 :                 return NT_STATUS_NO_MEMORY;
     805             :         }
     806           0 :         status = SMB_VFS_NEXT_CREATE_DFS_PATHAT(handle,
     807             :                         dirfsp,
     808             :                         cap_smb_fname,
     809             :                         reflist,
     810             :                         referral_count);
     811           0 :         TALLOC_FREE(cappath);
     812           0 :         TALLOC_FREE(cap_smb_fname);
     813           0 :         return status;
     814             : }
     815             : 
     816           0 : static NTSTATUS cap_read_dfs_pathat(struct vfs_handle_struct *handle,
     817             :                         TALLOC_CTX *mem_ctx,
     818             :                         struct files_struct *dirfsp,
     819             :                         struct smb_filename *smb_fname,
     820             :                         struct referral **ppreflist,
     821             :                         size_t *preferral_count)
     822             : {
     823           0 :         struct smb_filename *full_fname = NULL;
     824           0 :         struct smb_filename *cap_smb_fname = NULL;
     825           0 :         char *cappath = NULL;
     826             :         NTSTATUS status;
     827             : 
     828           0 :         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     829             :                                                 dirfsp,
     830             :                                                 smb_fname);
     831           0 :         if (full_fname == NULL) {
     832           0 :                 return NT_STATUS_NO_MEMORY;
     833             :         }
     834           0 :         cappath = capencode(talloc_tos(), full_fname->base_name);
     835           0 :         if (cappath == NULL) {
     836           0 :                 TALLOC_FREE(full_fname);
     837           0 :                 return NT_STATUS_NO_MEMORY;
     838             :         }
     839           0 :         cap_smb_fname = synthetic_smb_fname(talloc_tos(),
     840             :                                 cappath,
     841             :                                 NULL,
     842             :                                 NULL,
     843             :                                 smb_fname->twrp,
     844             :                                 smb_fname->flags);
     845           0 :         if (cap_smb_fname == NULL) {
     846           0 :                 TALLOC_FREE(full_fname);
     847           0 :                 TALLOC_FREE(cappath);
     848           0 :                 return NT_STATUS_NO_MEMORY;
     849             :         }
     850             : 
     851           0 :         status = SMB_VFS_NEXT_READ_DFS_PATHAT(handle,
     852             :                         mem_ctx,
     853             :                         handle->conn->cwd_fsp,
     854             :                         cap_smb_fname,
     855             :                         ppreflist,
     856             :                         preferral_count);
     857             : 
     858           0 :         if (NT_STATUS_IS_OK(status)) {
     859             :                 /* Return any stat(2) info. */
     860           0 :                 smb_fname->st = cap_smb_fname->st;
     861             :         }
     862             : 
     863           0 :         TALLOC_FREE(full_fname);
     864           0 :         TALLOC_FREE(cappath);
     865           0 :         TALLOC_FREE(cap_smb_fname);
     866           0 :         return status;
     867             : }
     868             : 
     869             : static struct vfs_fn_pointers vfs_cap_fns = {
     870             :         .disk_free_fn = cap_disk_free,
     871             :         .get_quota_fn = cap_get_quota,
     872             :         .readdir_fn = cap_readdir,
     873             :         .mkdirat_fn = cap_mkdirat,
     874             :         .openat_fn = cap_openat,
     875             :         .renameat_fn = cap_renameat,
     876             :         .stat_fn = cap_stat,
     877             :         .lstat_fn = cap_lstat,
     878             :         .unlinkat_fn = cap_unlinkat,
     879             :         .lchown_fn = cap_lchown,
     880             :         .chdir_fn = cap_chdir,
     881             :         .symlinkat_fn = cap_symlinkat,
     882             :         .readlinkat_fn = cap_readlinkat,
     883             :         .linkat_fn = cap_linkat,
     884             :         .mknodat_fn = cap_mknodat,
     885             :         .realpath_fn = cap_realpath,
     886             :         .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
     887             :         .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
     888             :         .fgetxattr_fn = cap_fgetxattr,
     889             :         .fremovexattr_fn = cap_fremovexattr,
     890             :         .fsetxattr_fn = cap_fsetxattr,
     891             :         .create_dfs_pathat_fn = cap_create_dfs_pathat,
     892             :         .read_dfs_pathat_fn = cap_read_dfs_pathat
     893             : };
     894             : 
     895             : static_decl_vfs;
     896          26 : NTSTATUS vfs_cap_init(TALLOC_CTX *ctx)
     897             : {
     898          26 :         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "cap",
     899             :                                 &vfs_cap_fns);
     900             : }
     901             : 
     902             : /* For CAP functions */
     903             : #define hex_tag ':'
     904             : #define hex2bin(c)              hex2bin_table[(unsigned char)(c)]
     905             : #define bin2hex(c)              bin2hex_table[(unsigned char)(c)]
     906             : #define is_hex(s)               ((s)[0] == hex_tag)
     907             : 
     908             : static unsigned char hex2bin_table[256] = {
     909             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
     910             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
     911             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
     912             : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
     913             : 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x40 */
     914             : 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
     915             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
     916             : 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x60 */
     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, /* 0x70 */
     919             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 */
     920             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 */
     921             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 */
     922             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 */
     923             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 */
     924             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 */
     925             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 */
     926             : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  /* 0xf0 */
     927             : };
     928             : static unsigned char bin2hex_table[256] = "0123456789abcdef";
     929             : 
     930             : /*******************************************************************
     931             :   original code -> ":xx"  - CAP format
     932             : ********************************************************************/
     933             : 
     934           0 : static char *capencode(TALLOC_CTX *ctx, const char *from)
     935             : {
     936           0 :         char *out = NULL;
     937             :         const char *p1;
     938           0 :         char *to = NULL;
     939           0 :         size_t len = 0;
     940             : 
     941           0 :         for (p1 = from; *p1; p1++) {
     942           0 :                 if ((unsigned char)*p1 >= 0x80) {
     943           0 :                         len += 3;
     944             :                 } else {
     945           0 :                         len++;
     946             :                 }
     947             :         }
     948           0 :         len++;
     949             : 
     950           0 :         to = talloc_array(ctx, char, len);
     951           0 :         if (!to) {
     952           0 :                 return NULL;
     953             :         }
     954             : 
     955           0 :         for (out = to; *from;) {
     956             :                 /* buffer husoku error */
     957           0 :                 if ((unsigned char)*from >= 0x80) {
     958           0 :                         *out++ = hex_tag;
     959           0 :                         *out++ = bin2hex (((*from)>>4)&0x0f);
     960           0 :                         *out++ = bin2hex ((*from)&0x0f);
     961           0 :                         from++;
     962             :                 } else {
     963           0 :                         *out++ = *from++;
     964             :                 }
     965             :         }
     966           0 :         *out = '\0';
     967           0 :         return to;
     968             : }
     969             : 
     970             : /*******************************************************************
     971             :   CAP -> original code
     972             : ********************************************************************/
     973             : /* ":xx" -> a byte */
     974             : 
     975           0 : static char *capdecode(TALLOC_CTX *ctx, const char *from)
     976             : {
     977             :         const char *p1;
     978           0 :         char *out = NULL;
     979           0 :         char *to = NULL;
     980           0 :         size_t len = 0;
     981             : 
     982           0 :         for (p1 = from; *p1; len++) {
     983           0 :                 if (is_hex(p1)) {
     984           0 :                         p1 += 3;
     985             :                 } else {
     986           0 :                         p1++;
     987             :                 }
     988             :         }
     989           0 :         len++;
     990             : 
     991           0 :         to = talloc_array(ctx, char, len);
     992           0 :         if (!to) {
     993           0 :                 return NULL;
     994             :         }
     995             : 
     996           0 :         for (out = to; *from;) {
     997           0 :                 if (is_hex(from)) {
     998           0 :                         *out++ = (hex2bin(from[1])<<4) | (hex2bin(from[2]));
     999           0 :                         from += 3;
    1000             :                 } else {
    1001           0 :                         *out++ = *from++;
    1002             :                 }
    1003             :         }
    1004           0 :         *out = '\0';
    1005           0 :         return to;
    1006             : }

Generated by: LCOV version 1.13