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

Generated by: LCOV version 1.14