LCOV - code coverage report
Current view: top level - source3/torture - cmd_vfs.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 269 1227 21.9 %
Date: 2021-09-23 10:06:22 Functions: 11 48 22.9 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    VFS module functions
       4             : 
       5             :    Copyright (C) Simo Sorce 2002
       6             :    Copyright (C) Eric Lorimer 2002
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "smbd/smbd.h"
      24             : #include "system/passwd.h"
      25             : #include "system/filesys.h"
      26             : #include "vfstest.h"
      27             : #include "../lib/util/util_pw.h"
      28             : #include "libcli/security/security.h"
      29             : #include "passdb/machine_sid.h"
      30             : 
      31             : static const char *null_string = "";
      32             : 
      33          20 : static uint32_t ssf_flags(void)
      34             : {
      35          20 :         return lp_posix_pathnames() ? SMB_FILENAME_POSIX_PATH : 0;
      36             : }
      37             : 
      38           0 : static NTSTATUS cmd_load_module(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
      39             : {
      40             :         int i;
      41             : 
      42           0 :         if (argc < 2) {
      43           0 :                 printf("Usage: load <modules>\n");
      44           0 :                 return NT_STATUS_OK;
      45             :         }
      46             : 
      47           0 :         for (i=argc-1;i>0;i--) {
      48           0 :                 if (!vfs_init_custom(vfs->conn, argv[i])) {
      49           0 :                         DEBUG(0, ("load: (vfs_init_custom failed for %s)\n", argv[i]));
      50           0 :                         return NT_STATUS_UNSUCCESSFUL;
      51             :                 }
      52             :         }
      53           0 :         printf("load: ok\n");
      54           0 :         return NT_STATUS_OK;
      55             : }
      56             : 
      57           0 : static NTSTATUS cmd_populate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
      58             : {
      59             :         char c;
      60             :         size_t size;
      61           0 :         if (argc != 3) {
      62           0 :                 printf("Usage: populate <char> <size>\n");
      63           0 :                 return NT_STATUS_OK;
      64             :         }
      65           0 :         c = argv[1][0];
      66           0 :         size = atoi(argv[2]);
      67           0 :         vfs->data = talloc_array(mem_ctx, char, size);
      68           0 :         if (vfs->data == NULL) {
      69           0 :                 printf("populate: error=-1 (not enough memory)");
      70           0 :                 return NT_STATUS_UNSUCCESSFUL;
      71             :         }
      72           0 :         memset(vfs->data, c, size);
      73           0 :         vfs->data_size = size;
      74           0 :         return NT_STATUS_OK;
      75             : }
      76             : 
      77           0 : static NTSTATUS cmd_show_data(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
      78             : {
      79             :         size_t offset;
      80             :         size_t len;
      81           0 :         if (argc != 1 && argc != 3) {
      82           0 :                 printf("Usage: showdata [<offset> <len>]\n");
      83           0 :                 return NT_STATUS_OK;
      84             :         }
      85           0 :         if (vfs->data == NULL || vfs->data_size == 0) {
      86           0 :                 printf("show_data: error=-1 (buffer empty)\n");
      87           0 :                 return NT_STATUS_UNSUCCESSFUL;
      88             :         }
      89             : 
      90           0 :         if (argc == 3) {
      91           0 :                 offset = atoi(argv[1]);
      92           0 :                 len = atoi(argv[2]);
      93             :         } else {
      94           0 :                 offset = 0;
      95           0 :                 len = vfs->data_size;
      96             :         }
      97           0 :         if ((offset + len) > vfs->data_size) {
      98           0 :                 printf("show_data: error=-1 (not enough data in buffer)\n");
      99           0 :                 return NT_STATUS_UNSUCCESSFUL;
     100             :         }
     101           0 :         dump_data(0, (uint8_t *)(vfs->data) + offset, len);
     102           0 :         return NT_STATUS_OK;
     103             : }
     104             : 
     105          10 : static NTSTATUS cmd_connect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     106             : {
     107          10 :         const struct loadparm_substitution *lp_sub =
     108             :                 loadparm_s3_global_substitution();
     109             : 
     110          10 :         SMB_VFS_CONNECT(vfs->conn, lp_servicename(talloc_tos(), lp_sub, SNUM(vfs->conn)), "vfstest");
     111          10 :         return NT_STATUS_OK;
     112             : }
     113             : 
     114           0 : static NTSTATUS cmd_disconnect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     115             : {
     116           0 :         SMB_VFS_DISCONNECT(vfs->conn);
     117           0 :         return NT_STATUS_OK;
     118             : }
     119             : 
     120           0 : static NTSTATUS cmd_disk_free(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     121             : {
     122           0 :         struct smb_filename *smb_fname = NULL;
     123             :         uint64_t diskfree, bsize, dfree, dsize;
     124           0 :         if (argc != 2) {
     125           0 :                 printf("Usage: disk_free <path>\n");
     126           0 :                 return NT_STATUS_OK;
     127             :         }
     128             : 
     129           0 :         smb_fname = synthetic_smb_fname(talloc_tos(),
     130           0 :                                         argv[1],
     131             :                                         NULL,
     132             :                                         NULL,
     133             :                                         0,
     134             :                                         ssf_flags());
     135           0 :         if (smb_fname == NULL) {
     136           0 :                 return NT_STATUS_NO_MEMORY;
     137             :         }
     138           0 :         diskfree = SMB_VFS_DISK_FREE(vfs->conn, smb_fname,
     139             :                                 &bsize, &dfree, &dsize);
     140           0 :         printf("disk_free: %lu, bsize = %lu, dfree = %lu, dsize = %lu\n",
     141             :                         (unsigned long)diskfree,
     142             :                         (unsigned long)bsize,
     143             :                         (unsigned long)dfree,
     144             :                         (unsigned long)dsize);
     145           0 :         return NT_STATUS_OK;
     146             : }
     147             : 
     148             : 
     149           0 : static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     150             : {
     151           0 :         struct smb_filename *smb_fname = NULL;
     152             : 
     153           0 :         if (argc != 2) {
     154           0 :                 printf("Usage: opendir <fname>\n");
     155           0 :                 return NT_STATUS_OK;
     156             :         }
     157             : 
     158           0 :         smb_fname = synthetic_smb_fname(talloc_tos(),
     159           0 :                                         argv[1],
     160             :                                         NULL,
     161             :                                         NULL,
     162             :                                         0,
     163             :                                         ssf_flags());
     164           0 :         if (smb_fname == NULL) {
     165           0 :                 return NT_STATUS_NO_MEMORY;
     166             :         }
     167             : 
     168           0 :         vfs->currentdir = OpenDir(vfs->conn, vfs->conn, smb_fname, NULL, 0);
     169           0 :         if (vfs->currentdir == NULL) {
     170           0 :                 printf("opendir error=%d (%s)\n", errno, strerror(errno));
     171           0 :                 TALLOC_FREE(smb_fname);
     172           0 :                 return NT_STATUS_UNSUCCESSFUL;
     173             :         }
     174             : 
     175           0 :         vfs->currentdir_offset = 0;
     176             : 
     177           0 :         TALLOC_FREE(smb_fname);
     178           0 :         printf("opendir: ok\n");
     179           0 :         return NT_STATUS_OK;
     180             : }
     181             : 
     182             : 
     183           0 : static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     184             : {
     185             :         SMB_STRUCT_STAT st;
     186           0 :         const char *dname = NULL;
     187           0 :         char *talloced = NULL;
     188             : 
     189           0 :         if (vfs->currentdir == NULL) {
     190           0 :                 printf("readdir: error=-1 (no open directory)\n");
     191           0 :                 return NT_STATUS_UNSUCCESSFUL;
     192             :         }
     193             : 
     194           0 :         dname = ReadDirName(vfs->currentdir,
     195             :                             &vfs->currentdir_offset,
     196             :                             &st,
     197             :                             &talloced);
     198           0 :         if (dname == NULL) {
     199           0 :                 printf("readdir: NULL\n");
     200           0 :                 return NT_STATUS_OK;
     201             :         }
     202             : 
     203           0 :         printf("readdir: %s\n", dname);
     204           0 :         if (VALID_STAT(st)) {
     205             :                 time_t tmp_time;
     206           0 :                 printf("  stat available");
     207           0 :                 if (S_ISREG(st.st_ex_mode)) printf("  Regular File\n");
     208           0 :                 else if (S_ISDIR(st.st_ex_mode)) printf("  Directory\n");
     209           0 :                 else if (S_ISCHR(st.st_ex_mode)) printf("  Character Device\n");
     210           0 :                 else if (S_ISBLK(st.st_ex_mode)) printf("  Block Device\n");
     211           0 :                 else if (S_ISFIFO(st.st_ex_mode)) printf("  Fifo\n");
     212           0 :                 else if (S_ISLNK(st.st_ex_mode)) printf("  Symbolic Link\n");
     213           0 :                 else if (S_ISSOCK(st.st_ex_mode)) printf("  Socket\n");
     214           0 :                 printf("  Size: %10u", (unsigned int)st.st_ex_size);
     215             : #ifdef HAVE_STAT_ST_BLOCKS
     216           0 :                 printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks);
     217             : #endif
     218             : #ifdef HAVE_STAT_ST_BLKSIZE
     219           0 :                 printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize);
     220             : #endif
     221           0 :                 printf("  Device: 0x%10x", (unsigned int)st.st_ex_dev);
     222           0 :                 printf(" Inode: %10u", (unsigned int)st.st_ex_ino);
     223           0 :                 printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink);
     224           0 :                 printf("  Access: %05o", (int)((st.st_ex_mode) & 007777));
     225           0 :                 printf(" Uid: %5lu Gid: %5lu\n",
     226           0 :                        (unsigned long)st.st_ex_uid,
     227           0 :                        (unsigned long)st.st_ex_gid);
     228           0 :                 tmp_time = convert_timespec_to_time_t(st.st_ex_atime);
     229           0 :                 printf("  Access: %s", ctime(&tmp_time));
     230           0 :                 tmp_time = convert_timespec_to_time_t(st.st_ex_mtime);
     231           0 :                 printf("  Modify: %s", ctime(&tmp_time));
     232           0 :                 tmp_time = convert_timespec_to_time_t(st.st_ex_ctime);
     233           0 :                 printf("  Change: %s", ctime(&tmp_time));
     234             :         }
     235             : 
     236           0 :         TALLOC_FREE(talloced);
     237           0 :         return NT_STATUS_OK;
     238             : }
     239             : 
     240             : 
     241           4 : static NTSTATUS cmd_mkdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     242             : {
     243           4 :         struct smb_filename *smb_fname = NULL;
     244             :         int ret;
     245             : 
     246           4 :         if (argc != 2) {
     247           0 :                 printf("Usage: mkdir <path>\n");
     248           0 :                 return NT_STATUS_OK;
     249             :         }
     250             : 
     251           8 :         smb_fname = synthetic_smb_fname(talloc_tos(),
     252           4 :                                         argv[1],
     253             :                                         NULL,
     254             :                                         NULL,
     255             :                                         0,
     256             :                                         ssf_flags());
     257             : 
     258           4 :         if (smb_fname == NULL) {
     259           0 :                 return NT_STATUS_NO_MEMORY;
     260             :         }
     261             : 
     262           4 :         ret = SMB_VFS_MKDIRAT(vfs->conn,
     263             :                                 vfs->conn->cwd_fsp,
     264             :                                 smb_fname,
     265             :                                 00755);
     266           4 :         if (ret == -1) {
     267           0 :                 printf("mkdir error=%d (%s)\n", errno, strerror(errno));
     268           0 :                 return NT_STATUS_UNSUCCESSFUL;
     269             :         }
     270             : 
     271           4 :         printf("mkdir: ok\n");
     272           4 :         return NT_STATUS_OK;
     273             : }
     274             : 
     275             : 
     276           0 : static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     277             : {
     278           0 :         if (vfs->currentdir == NULL) {
     279           0 :                 printf("closedir: failure (no directory open)\n");
     280           0 :                 return NT_STATUS_UNSUCCESSFUL;
     281             :         }
     282             : 
     283           0 :         TALLOC_FREE(vfs->currentdir);
     284           0 :         vfs->currentdir_offset = 0;
     285             : 
     286           0 :         printf("closedir: ok\n");
     287           0 :         return NT_STATUS_OK;
     288             : }
     289             : 
     290             : 
     291           6 : static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     292             : {
     293             :         int flags;
     294             :         mode_t mode;
     295             :         const char *flagstr;
     296             :         files_struct *fsp;
     297           6 :         struct files_struct *fspcwd = NULL;
     298           6 :         struct smb_filename *smb_fname = NULL;
     299             :         NTSTATUS status;
     300             :         int ret;
     301             :         int fd;
     302             : 
     303           6 :         mode = 00400;
     304             : 
     305           6 :         if (argc < 3 || argc > 5) {
     306           0 :                 printf("Usage: open <filename> <flags> <mode>\n");
     307           0 :                 printf("  flags: O = O_RDONLY\n");
     308           0 :                 printf("         R = O_RDWR\n");
     309           0 :                 printf("         W = O_WRONLY\n");
     310           0 :                 printf("         C = O_CREAT\n");
     311           0 :                 printf("         E = O_EXCL\n");
     312           0 :                 printf("         T = O_TRUNC\n");
     313           0 :                 printf("         A = O_APPEND\n");
     314           0 :                 printf("         N = O_NONBLOCK/O_NDELAY\n");
     315             : #ifdef O_SYNC
     316           0 :                 printf("         S = O_SYNC\n");
     317             : #endif
     318             : #ifdef O_NOFOLLOW
     319           0 :                 printf("         F = O_NOFOLLOW\n");
     320             : #endif
     321           0 :                 printf("  mode: see open.2\n");
     322           0 :                 printf("        mode is ignored if C flag not present\n");
     323           0 :                 printf("        mode defaults to 00400\n");
     324           0 :                 return NT_STATUS_OK;
     325             :         }
     326           6 :         flags = 0;
     327           6 :         flagstr = argv[2];
     328          24 :         while (*flagstr) {
     329          12 :                 switch (*flagstr) {
     330           0 :                 case 'O':
     331           0 :                         flags |= O_RDONLY;
     332           0 :                         break;
     333           6 :                 case 'R':
     334           6 :                         flags |= O_RDWR;
     335           6 :                         break;
     336           0 :                 case 'W':
     337           0 :                         flags |= O_WRONLY;
     338           0 :                         break;
     339           6 :                 case 'C':
     340           6 :                         flags |= O_CREAT;
     341           6 :                         break;
     342           0 :                 case 'E':
     343           0 :                         flags |= O_EXCL;
     344           0 :                         break;
     345           0 :                 case 'T':
     346           0 :                         flags |= O_TRUNC;
     347           0 :                         break;
     348           0 :                 case 'A':
     349           0 :                         flags |= O_APPEND;
     350           0 :                         break;
     351           0 :                 case 'N':
     352           0 :                         flags |= O_NONBLOCK;
     353           0 :                         break;
     354             : #ifdef O_SYNC
     355           0 :                 case 'S':
     356           0 :                         flags |= O_SYNC;
     357           0 :                         break;
     358             : #endif
     359             : #ifdef O_NOFOLLOW
     360           0 :                 case 'F':
     361           0 :                         flags |= O_NOFOLLOW;
     362           0 :                         break;
     363             : #endif
     364           0 :                 default:
     365           0 :                         printf("open: error=-1 (invalid flag!)\n");
     366           0 :                         return NT_STATUS_UNSUCCESSFUL;
     367             :                 }
     368          12 :                 flagstr++;
     369             :         }
     370           6 :         if ((flags & O_CREAT) && argc == 4) {
     371           6 :                 if (sscanf(argv[3], "%ho", (unsigned short *)&mode) == 0) {
     372           0 :                         printf("open: error=-1 (invalid mode!)\n");
     373           0 :                         return NT_STATUS_UNSUCCESSFUL;
     374             :                 }
     375             :         }
     376             : 
     377           6 :         fsp = talloc_zero(vfs, struct files_struct);
     378           6 :         if (fsp == NULL) {
     379           0 :                 return NT_STATUS_NO_MEMORY;
     380             :         }
     381           6 :         fsp->fh = fd_handle_create(fsp);
     382           6 :         if (fsp->fh == NULL) {
     383           0 :                 TALLOC_FREE(fsp);
     384           0 :                 return NT_STATUS_NO_MEMORY;
     385             :         }
     386           6 :         fsp->conn = vfs->conn;
     387             : 
     388          12 :         smb_fname = synthetic_smb_fname_split(NULL,
     389           6 :                                         argv[1],
     390           6 :                                         lp_posix_pathnames());
     391           6 :         if (smb_fname == NULL) {
     392           0 :                 TALLOC_FREE(fsp);
     393           0 :                 return NT_STATUS_NO_MEMORY;
     394             :         }
     395             : 
     396           6 :         fsp->fsp_name = smb_fname;
     397             : 
     398           6 :         status = vfs_at_fspcwd(fsp, vfs->conn, &fspcwd);
     399           6 :         if (!NT_STATUS_IS_OK(status)) {
     400           0 :                 return status;
     401             :         }
     402             : 
     403           6 :         fd = SMB_VFS_OPENAT(vfs->conn,
     404             :                             fspcwd,
     405             :                             smb_fname,
     406             :                             fsp,
     407             :                             flags,
     408             :                             mode);
     409           6 :         if (fd == -1) {
     410           0 :                 printf("open: error=%d (%s)\n", errno, strerror(errno));
     411           0 :                 TALLOC_FREE(fsp);
     412           0 :                 TALLOC_FREE(smb_fname);
     413           0 :                 return NT_STATUS_UNSUCCESSFUL;
     414             :         }
     415           6 :         fsp_set_fd(fsp, fd);
     416             : 
     417           6 :         status = NT_STATUS_OK;
     418           6 :         ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
     419           6 :         if (ret == -1) {
     420             :                 /* If we have an fd, this stat should succeed. */
     421           0 :                 DEBUG(0,("Error doing fstat on open file %s "
     422             :                          "(%s)\n",
     423             :                          smb_fname_str_dbg(smb_fname),
     424             :                          strerror(errno) ));
     425           0 :                 status = map_nt_error_from_unix(errno);
     426           6 :         } else if (S_ISDIR(smb_fname->st.st_ex_mode)) {
     427           0 :                 errno = EISDIR;
     428           0 :                 status = NT_STATUS_FILE_IS_A_DIRECTORY;
     429             :         }
     430             : 
     431           6 :         if (!NT_STATUS_IS_OK(status)) {
     432           0 :                 SMB_VFS_CLOSE(fsp);
     433           0 :                 TALLOC_FREE(fsp);
     434           0 :                 TALLOC_FREE(smb_fname);
     435           0 :                 return status;
     436             :         }
     437             : 
     438           6 :         fsp->file_id = vfs_file_id_from_sbuf(vfs->conn, &smb_fname->st);
     439           6 :         fsp->vuid = UID_FIELD_INVALID;
     440           6 :         fsp->file_pid = 0;
     441           6 :         fsp->fsp_flags.can_lock = true;
     442           6 :         fsp->fsp_flags.can_read = true;
     443           6 :         fsp->fsp_flags.can_write = CAN_WRITE(vfs->conn);
     444           6 :         fsp->print_file = NULL;
     445           6 :         fsp->fsp_flags.modified = false;
     446           6 :         fsp->sent_oplock_break = NO_BREAK_SENT;
     447           6 :         fsp->fsp_flags.is_directory = false;
     448             : 
     449           6 :         vfs->files[fsp_get_pathref_fd(fsp)] = fsp;
     450           6 :         printf("open: fd=%d\n", fsp_get_pathref_fd(fsp));
     451           6 :         return NT_STATUS_OK;
     452             : }
     453             : 
     454             : 
     455           6 : static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     456             : {
     457           6 :         struct smb_filename *smb_fname = NULL;
     458           6 :         int ret = -1;
     459             : 
     460           6 :         if (argc != 2) {
     461           0 :                 printf("Usage: %s <path>\n", argv[0]);
     462           0 :                 return NT_STATUS_OK;
     463             :         }
     464             : 
     465          12 :         smb_fname = synthetic_smb_fname(talloc_tos(),
     466           6 :                                         argv[1],
     467             :                                         NULL,
     468             :                                         NULL,
     469             :                                         0,
     470             :                                         ssf_flags());
     471             : 
     472           6 :         if (smb_fname == NULL) {
     473           0 :                 return NT_STATUS_NO_MEMORY;
     474             :         }
     475             : 
     476           6 :         if (strcmp("rmdir", argv[0]) == 0 ) {
     477           2 :                 ret = SMB_VFS_UNLINKAT(vfs->conn,
     478             :                                 vfs->conn->cwd_fsp,
     479             :                                 smb_fname,
     480             :                                 AT_REMOVEDIR);
     481           2 :                 TALLOC_FREE(smb_fname);
     482           4 :         } else if (strcmp("unlink", argv[0]) == 0 ) {
     483           4 :                 TALLOC_FREE(smb_fname);
     484             :                 /* unlink can be a stream:name */
     485           8 :                 smb_fname = synthetic_smb_fname_split(talloc_tos(),
     486           4 :                                         argv[1],
     487           4 :                                         lp_posix_pathnames());
     488           4 :                 if (smb_fname == NULL) {
     489           0 :                         return NT_STATUS_NO_MEMORY;
     490             :                 }
     491           4 :                 ret = SMB_VFS_UNLINKAT(vfs->conn,
     492             :                                 vfs->conn->cwd_fsp,
     493             :                                 smb_fname,
     494             :                                 0);
     495           4 :                 TALLOC_FREE(smb_fname);
     496           0 :         } else if (strcmp("chdir", argv[0]) == 0 ) {
     497           0 :                 ret = SMB_VFS_CHDIR(vfs->conn, smb_fname);
     498           0 :                 TALLOC_FREE(smb_fname);
     499             :         } else {
     500           0 :                 printf("%s: error=%d (invalid function name!)\n", argv[0], errno);
     501           0 :                 return NT_STATUS_UNSUCCESSFUL;
     502             :         }
     503             : 
     504           6 :         if (ret == -1) {
     505           0 :                 printf("%s: error=%d (%s)\n", argv[0], errno, strerror(errno));
     506           0 :                 return NT_STATUS_UNSUCCESSFUL;
     507             :         }
     508             : 
     509           6 :         printf("%s: ok\n", argv[0]);
     510           6 :         return NT_STATUS_OK;
     511             : }
     512             : 
     513             : 
     514           0 : static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     515             : {
     516             :         int fd, ret;
     517             : 
     518           0 :         if (argc != 2) {
     519           0 :                 printf("Usage: close <fd>\n");
     520           0 :                 return NT_STATUS_OK;
     521             :         }
     522             : 
     523           0 :         fd = atoi(argv[1]);
     524           0 :         if (vfs->files[fd] == NULL) {
     525           0 :                 printf("close: error=-1 (invalid file descriptor)\n");
     526           0 :                 return NT_STATUS_OK;
     527             :         }
     528             : 
     529           0 :         ret = SMB_VFS_CLOSE(vfs->files[fd]);
     530           0 :         if (ret == -1 )
     531           0 :                 printf("close: error=%d (%s)\n", errno, strerror(errno));
     532             :         else
     533           0 :                 printf("close: ok\n");
     534             : 
     535           0 :         TALLOC_FREE(vfs->files[fd]);
     536           0 :         vfs->files[fd] = NULL;
     537           0 :         return NT_STATUS_OK;
     538             : }
     539             : 
     540             : 
     541           0 : static NTSTATUS cmd_read(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     542             : {
     543             :         int fd;
     544             :         size_t size, rsize;
     545             : 
     546           0 :         if (argc != 3) {
     547           0 :                 printf("Usage: read <fd> <size>\n");
     548           0 :                 return NT_STATUS_OK;
     549             :         }
     550             : 
     551             :         /* do some error checking on these */
     552           0 :         fd = atoi(argv[1]);
     553           0 :         size = atoi(argv[2]);
     554           0 :         vfs->data = talloc_array(mem_ctx, char, size);
     555           0 :         if (vfs->data == NULL) {
     556           0 :                 printf("read: error=-1 (not enough memory)");
     557           0 :                 return NT_STATUS_UNSUCCESSFUL;
     558             :         }
     559           0 :         vfs->data_size = size;
     560             : 
     561           0 :         rsize = read_file(vfs->files[fd], vfs->data, 0, size);
     562           0 :         if (rsize == -1) {
     563           0 :                 printf("read: error=%d (%s)\n", errno, strerror(errno));
     564           0 :                 return NT_STATUS_UNSUCCESSFUL;
     565             :         }
     566             : 
     567           0 :         printf("read: ok\n");
     568           0 :         return NT_STATUS_OK;
     569             : }
     570             : 
     571             : 
     572           0 : static NTSTATUS cmd_write(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     573             : {
     574             :         int fd, size, wsize;
     575             : 
     576           0 :         if (argc != 3) {
     577           0 :                 printf("Usage: write <fd> <size>\n");
     578           0 :                 return NT_STATUS_OK;
     579             :         }
     580             : 
     581             :         /* some error checking should go here */
     582           0 :         fd = atoi(argv[1]);
     583           0 :         size = atoi(argv[2]);
     584           0 :         if (vfs->data == NULL) {
     585           0 :                 printf("write: error=-1 (buffer empty, please populate it before writing)");
     586           0 :                 return NT_STATUS_UNSUCCESSFUL;
     587             :         }
     588             : 
     589           0 :         if (vfs->data_size < size) {
     590           0 :                 printf("write: error=-1 (buffer too small, please put some more data in)");
     591           0 :                 return NT_STATUS_UNSUCCESSFUL;
     592             :         }
     593             : 
     594           0 :         wsize = write_file(NULL, vfs->files[fd], vfs->data, 0, size);
     595             : 
     596           0 :         if (wsize == -1) {
     597           0 :                 printf("write: error=%d (%s)\n", errno, strerror(errno));
     598           0 :                 return NT_STATUS_UNSUCCESSFUL;
     599             :         }
     600             : 
     601           0 :         printf("write: ok\n");
     602           0 :         return NT_STATUS_OK;
     603             : }
     604             : 
     605             : 
     606           0 : static NTSTATUS cmd_lseek(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     607             : {
     608             :         int fd, offset, whence;
     609             :         off_t pos;
     610             : 
     611           0 :         if (argc != 4) {
     612           0 :                 printf("Usage: lseek <fd> <offset> <whence>\n...where whence is 1 => SEEK_SET, 2 => SEEK_CUR, 3 => SEEK_END\n");
     613           0 :                 return NT_STATUS_OK;
     614             :         }
     615             : 
     616           0 :         fd = atoi(argv[1]);
     617           0 :         offset = atoi(argv[2]);
     618           0 :         whence = atoi(argv[3]);
     619           0 :         switch (whence) {
     620           0 :                 case 1:         whence = SEEK_SET; break;
     621           0 :                 case 2:         whence = SEEK_CUR; break;
     622           0 :                 default:        whence = SEEK_END;
     623             :         }
     624             : 
     625           0 :         pos = SMB_VFS_LSEEK(vfs->files[fd], offset, whence);
     626           0 :         if (pos == (off_t)-1) {
     627           0 :                 printf("lseek: error=%d (%s)\n", errno, strerror(errno));
     628           0 :                 return NT_STATUS_UNSUCCESSFUL;
     629             :         }
     630             : 
     631           0 :         printf("lseek: ok\n");
     632           0 :         return NT_STATUS_OK;
     633             : }
     634             : 
     635             : 
     636           0 : static NTSTATUS cmd_rename(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     637             : {
     638             :         int ret;
     639           0 :         struct smb_filename *smb_fname_src = NULL;
     640           0 :         struct smb_filename *smb_fname_dst = NULL;
     641             : 
     642           0 :         if (argc != 3) {
     643           0 :                 printf("Usage: rename <old> <new>\n");
     644           0 :                 return NT_STATUS_OK;
     645             :         }
     646             : 
     647           0 :         smb_fname_src = synthetic_smb_fname_split(mem_ctx,
     648           0 :                                         argv[1],
     649           0 :                                         lp_posix_pathnames());
     650           0 :         if (smb_fname_src == NULL) {
     651           0 :                 return NT_STATUS_NO_MEMORY;
     652             :         }
     653             : 
     654           0 :         smb_fname_dst = synthetic_smb_fname_split(mem_ctx,
     655           0 :                                         argv[2],
     656           0 :                                         lp_posix_pathnames());
     657           0 :         if (smb_fname_dst == NULL) {
     658           0 :                 TALLOC_FREE(smb_fname_src);
     659           0 :                 return NT_STATUS_NO_MEMORY;
     660             :         }
     661             : 
     662           0 :         ret = SMB_VFS_RENAMEAT(vfs->conn,
     663             :                         vfs->conn->cwd_fsp,
     664             :                         smb_fname_src,
     665             :                         vfs->conn->cwd_fsp,
     666             :                         smb_fname_dst);
     667             : 
     668           0 :         TALLOC_FREE(smb_fname_src);
     669           0 :         TALLOC_FREE(smb_fname_dst);
     670           0 :         if (ret == -1) {
     671           0 :                 printf("rename: error=%d (%s)\n", errno, strerror(errno));
     672           0 :                 return NT_STATUS_UNSUCCESSFUL;
     673             :         }
     674             : 
     675           0 :         printf("rename: ok\n");
     676           0 :         return NT_STATUS_OK;
     677             : }
     678             : 
     679           0 : static NTSTATUS cmd_fsync(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     680             : {
     681             :         int ret, fd;
     682           0 :         if (argc != 2) {
     683           0 :                 printf("Usage: fsync <fd>\n");
     684           0 :                 return NT_STATUS_OK;
     685             :         }
     686             : 
     687           0 :         fd = atoi(argv[1]);
     688           0 :         ret = smb_vfs_fsync_sync(vfs->files[fd]);
     689           0 :         if (ret == -1) {
     690           0 :                 printf("fsync: error=%d (%s)\n", errno, strerror(errno));
     691           0 :                 return NT_STATUS_UNSUCCESSFUL;
     692             :         }
     693             : 
     694           0 :         printf("fsync: ok\n");
     695           0 :         return NT_STATUS_OK;
     696             : }
     697             : 
     698             : 
     699           2 : static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     700             : {
     701             :         int ret;
     702             :         const char *user;
     703             :         const char *group;
     704           2 :         struct passwd *pwd = NULL;
     705           2 :         struct group *grp = NULL;
     706           2 :         struct smb_filename *smb_fname = NULL;
     707             :         SMB_STRUCT_STAT st;
     708             :         time_t tmp_time;
     709             : 
     710           2 :         if (argc != 2) {
     711           0 :                 printf("Usage: stat <fname>\n");
     712           0 :                 return NT_STATUS_OK;
     713             :         }
     714             : 
     715           4 :         smb_fname = synthetic_smb_fname_split(mem_ctx,
     716           2 :                                         argv[1],
     717           2 :                                         lp_posix_pathnames());
     718           2 :         if (smb_fname == NULL) {
     719           0 :                 return NT_STATUS_NO_MEMORY;
     720             :         }
     721             : 
     722           2 :         ret = SMB_VFS_STAT(vfs->conn, smb_fname);
     723           2 :         if (ret == -1) {
     724           0 :                 printf("stat: error=%d (%s)\n", errno, strerror(errno));
     725           0 :                 TALLOC_FREE(smb_fname);
     726           0 :                 return NT_STATUS_UNSUCCESSFUL;
     727             :         }
     728           2 :         st = smb_fname->st;
     729           2 :         TALLOC_FREE(smb_fname);
     730             : 
     731           2 :         pwd = getpwuid(st.st_ex_uid);
     732           2 :         if (pwd != NULL) user = pwd->pw_name;
     733           0 :         else user = null_string;
     734           2 :         grp = getgrgid(st.st_ex_gid);
     735           2 :         if (grp != NULL) group = grp->gr_name;
     736           0 :         else group = null_string;
     737             : 
     738           2 :         printf("stat: ok\n");
     739           2 :         printf("  File: %s", argv[1]);
     740           2 :         if (S_ISREG(st.st_ex_mode)) printf("  Regular File\n");
     741           0 :         else if (S_ISDIR(st.st_ex_mode)) printf("  Directory\n");
     742           0 :         else if (S_ISCHR(st.st_ex_mode)) printf("  Character Device\n");
     743           0 :         else if (S_ISBLK(st.st_ex_mode)) printf("  Block Device\n");
     744           0 :         else if (S_ISFIFO(st.st_ex_mode)) printf("  Fifo\n");
     745           0 :         else if (S_ISLNK(st.st_ex_mode)) printf("  Symbolic Link\n");
     746           0 :         else if (S_ISSOCK(st.st_ex_mode)) printf("  Socket\n");
     747           2 :         printf("  Size: %10u", (unsigned int)st.st_ex_size);
     748             : #ifdef HAVE_STAT_ST_BLOCKS
     749           2 :         printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks);
     750             : #endif
     751             : #ifdef HAVE_STAT_ST_BLKSIZE
     752           2 :         printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize);
     753             : #endif
     754           2 :         printf("  Device: 0x%10x", (unsigned int)st.st_ex_dev);
     755           2 :         printf(" Inode: %10u", (unsigned int)st.st_ex_ino);
     756           2 :         printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink);
     757           2 :         printf("  Access: %05o", (int)((st.st_ex_mode) & 007777));
     758           2 :         printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_ex_uid, user,
     759           2 :                (unsigned long)st.st_ex_gid, group);
     760           2 :         tmp_time = convert_timespec_to_time_t(st.st_ex_atime);
     761           2 :         printf("  Access: %s", ctime(&tmp_time));
     762           2 :         tmp_time = convert_timespec_to_time_t(st.st_ex_mtime);
     763           2 :         printf("  Modify: %s", ctime(&tmp_time));
     764           2 :         tmp_time = convert_timespec_to_time_t(st.st_ex_ctime);
     765           2 :         printf("  Change: %s", ctime(&tmp_time));
     766             : 
     767           2 :         return NT_STATUS_OK;
     768             : }
     769             : 
     770             : 
     771           0 : static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     772             : {
     773             :         int fd;
     774             :         const char *user;
     775             :         const char *group;
     776           0 :         struct passwd *pwd = NULL;
     777           0 :         struct group *grp = NULL;
     778             :         SMB_STRUCT_STAT st;
     779             :         time_t tmp_time;
     780             : 
     781           0 :         if (argc != 2) {
     782           0 :                 printf("Usage: fstat <fd>\n");
     783           0 :                 return NT_STATUS_OK;
     784             :         }
     785             : 
     786           0 :         fd = atoi(argv[1]);
     787           0 :         if (fd < 0 || fd >= 1024) {
     788           0 :                 printf("fstat: error=%d (file descriptor out of range)\n", EBADF);
     789           0 :                 return NT_STATUS_OK;
     790             :         }
     791             : 
     792           0 :         if (vfs->files[fd] == NULL) {
     793           0 :                 printf("fstat: error=%d (invalid file descriptor)\n", EBADF);
     794           0 :                 return NT_STATUS_OK;
     795             :         }
     796             : 
     797           0 :         if (SMB_VFS_FSTAT(vfs->files[fd], &st) == -1) {
     798           0 :                 printf("fstat: error=%d (%s)\n", errno, strerror(errno));
     799           0 :                 return NT_STATUS_UNSUCCESSFUL;
     800             :         }
     801             : 
     802           0 :         pwd = getpwuid(st.st_ex_uid);
     803           0 :         if (pwd != NULL) user = pwd->pw_name;
     804           0 :         else user = null_string;
     805           0 :         grp = getgrgid(st.st_ex_gid);
     806           0 :         if (grp != NULL) group = grp->gr_name;
     807           0 :         else group = null_string;
     808             : 
     809           0 :         printf("fstat: ok\n");
     810           0 :         if (S_ISREG(st.st_ex_mode)) printf("  Regular File\n");
     811           0 :         else if (S_ISDIR(st.st_ex_mode)) printf("  Directory\n");
     812           0 :         else if (S_ISCHR(st.st_ex_mode)) printf("  Character Device\n");
     813           0 :         else if (S_ISBLK(st.st_ex_mode)) printf("  Block Device\n");
     814           0 :         else if (S_ISFIFO(st.st_ex_mode)) printf("  Fifo\n");
     815           0 :         else if (S_ISLNK(st.st_ex_mode)) printf("  Symbolic Link\n");
     816           0 :         else if (S_ISSOCK(st.st_ex_mode)) printf("  Socket\n");
     817           0 :         printf("  Size: %10u", (unsigned int)st.st_ex_size);
     818             : #ifdef HAVE_STAT_ST_BLOCKS
     819           0 :         printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks);
     820             : #endif
     821             : #ifdef HAVE_STAT_ST_BLKSIZE
     822           0 :         printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize);
     823             : #endif
     824           0 :         printf("  Device: 0x%10x", (unsigned int)st.st_ex_dev);
     825           0 :         printf(" Inode: %10u", (unsigned int)st.st_ex_ino);
     826           0 :         printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink);
     827           0 :         printf("  Access: %05o", (int)((st.st_ex_mode) & 007777));
     828           0 :         printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_ex_uid, user,
     829           0 :                (unsigned long)st.st_ex_gid, group);
     830           0 :         tmp_time = convert_timespec_to_time_t(st.st_ex_atime);
     831           0 :         printf("  Access: %s", ctime(&tmp_time));
     832           0 :         tmp_time = convert_timespec_to_time_t(st.st_ex_mtime);
     833           0 :         printf("  Modify: %s", ctime(&tmp_time));
     834           0 :         tmp_time = convert_timespec_to_time_t(st.st_ex_ctime);
     835           0 :         printf("  Change: %s", ctime(&tmp_time));
     836             : 
     837           0 :         return NT_STATUS_OK;
     838             : }
     839             : 
     840             : 
     841           0 : static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     842             : {
     843             :         const char *user;
     844             :         const char *group;
     845           0 :         struct passwd *pwd = NULL;
     846           0 :         struct group *grp = NULL;
     847           0 :         struct smb_filename *smb_fname = NULL;
     848             :         SMB_STRUCT_STAT st;
     849             :         time_t tmp_time;
     850             : 
     851           0 :         if (argc != 2) {
     852           0 :                 printf("Usage: lstat <path>\n");
     853           0 :                 return NT_STATUS_OK;
     854             :         }
     855             : 
     856           0 :         smb_fname = synthetic_smb_fname_split(mem_ctx,
     857           0 :                                         argv[1],
     858           0 :                                         lp_posix_pathnames());
     859           0 :         if (smb_fname == NULL) {
     860           0 :                 return NT_STATUS_NO_MEMORY;
     861             :         }
     862             : 
     863           0 :         if (SMB_VFS_LSTAT(vfs->conn, smb_fname) == -1) {
     864           0 :                 printf("lstat: error=%d (%s)\n", errno, strerror(errno));
     865           0 :                 TALLOC_FREE(smb_fname);
     866           0 :                 return NT_STATUS_UNSUCCESSFUL;
     867             :         }
     868           0 :         st = smb_fname->st;
     869           0 :         TALLOC_FREE(smb_fname);
     870             : 
     871           0 :         pwd = getpwuid(st.st_ex_uid);
     872           0 :         if (pwd != NULL) user = pwd->pw_name;
     873           0 :         else user = null_string;
     874           0 :         grp = getgrgid(st.st_ex_gid);
     875           0 :         if (grp != NULL) group = grp->gr_name;
     876           0 :         else group = null_string;
     877             : 
     878           0 :         printf("lstat: ok\n");
     879           0 :         if (S_ISREG(st.st_ex_mode)) printf("  Regular File\n");
     880           0 :         else if (S_ISDIR(st.st_ex_mode)) printf("  Directory\n");
     881           0 :         else if (S_ISCHR(st.st_ex_mode)) printf("  Character Device\n");
     882           0 :         else if (S_ISBLK(st.st_ex_mode)) printf("  Block Device\n");
     883           0 :         else if (S_ISFIFO(st.st_ex_mode)) printf("  Fifo\n");
     884           0 :         else if (S_ISLNK(st.st_ex_mode)) printf("  Symbolic Link\n");
     885           0 :         else if (S_ISSOCK(st.st_ex_mode)) printf("  Socket\n");
     886           0 :         printf("  Size: %10u", (unsigned int)st.st_ex_size);
     887             : #ifdef HAVE_STAT_ST_BLOCKS
     888           0 :         printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks);
     889             : #endif
     890             : #ifdef HAVE_STAT_ST_BLKSIZE
     891           0 :         printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize);
     892             : #endif
     893           0 :         printf("  Device: 0x%10x", (unsigned int)st.st_ex_dev);
     894           0 :         printf(" Inode: %10u", (unsigned int)st.st_ex_ino);
     895           0 :         printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink);
     896           0 :         printf("  Access: %05o", (int)((st.st_ex_mode) & 007777));
     897           0 :         printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_ex_uid, user,
     898           0 :                (unsigned long)st.st_ex_gid, group);
     899           0 :         tmp_time = convert_timespec_to_time_t(st.st_ex_atime);
     900           0 :         printf("  Access: %s", ctime(&tmp_time));
     901           0 :         tmp_time = convert_timespec_to_time_t(st.st_ex_mtime);
     902           0 :         printf("  Modify: %s", ctime(&tmp_time));
     903           0 :         tmp_time = convert_timespec_to_time_t(st.st_ex_ctime);
     904           0 :         printf("  Change: %s", ctime(&tmp_time));
     905             : 
     906           0 :         return NT_STATUS_OK;
     907             : }
     908             : 
     909             : 
     910           0 : static NTSTATUS cmd_chmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     911             : {
     912           0 :         struct smb_filename *smb_fname = NULL;
     913             :         mode_t mode;
     914           0 :         struct smb_filename *pathref_fname = NULL;
     915             :         NTSTATUS status;
     916           0 :         if (argc != 3) {
     917           0 :                 printf("Usage: chmod <path> <mode>\n");
     918           0 :                 return NT_STATUS_OK;
     919             :         }
     920             : 
     921           0 :         mode = atoi(argv[2]);
     922             : 
     923           0 :         smb_fname = synthetic_smb_fname_split(mem_ctx,
     924           0 :                                         argv[1],
     925           0 :                                         lp_posix_pathnames());
     926           0 :         if (smb_fname == NULL) {
     927           0 :                 return NT_STATUS_NO_MEMORY;
     928             :         }
     929             : 
     930           0 :         status = synthetic_pathref(mem_ctx,
     931           0 :                                 vfs->conn->cwd_fsp,
     932           0 :                                 smb_fname->base_name,
     933             :                                 NULL,
     934             :                                 NULL,
     935             :                                 smb_fname->twrp,
     936             :                                 smb_fname->flags,
     937             :                                 &pathref_fname);
     938           0 :         if (!NT_STATUS_IS_OK(status)) {
     939           0 :                 return status;
     940             :         }
     941           0 :         if (SMB_VFS_FCHMOD(pathref_fname->fsp, mode) == -1) {
     942           0 :                 printf("chmod: error=%d (%s)\n", errno, strerror(errno));
     943           0 :                 return NT_STATUS_UNSUCCESSFUL;
     944             :         }
     945             : 
     946           0 :         printf("chmod: ok\n");
     947           0 :         return NT_STATUS_OK;
     948             : }
     949             : 
     950             : 
     951           0 : static NTSTATUS cmd_fchmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     952             : {
     953             :         int fd;
     954             :         mode_t mode;
     955           0 :         if (argc != 3) {
     956           0 :                 printf("Usage: fchmod <fd> <mode>\n");
     957           0 :                 return NT_STATUS_OK;
     958             :         }
     959             : 
     960           0 :         fd = atoi(argv[1]);
     961           0 :         mode = atoi(argv[2]);
     962           0 :         if (fd < 0 || fd >= 1024) {
     963           0 :                 printf("fchmod: error=%d (file descriptor out of range)\n", EBADF);
     964           0 :                 return NT_STATUS_OK;
     965             :         }
     966           0 :         if (vfs->files[fd] == NULL) {
     967           0 :                 printf("fchmod: error=%d (invalid file descriptor)\n", EBADF);
     968           0 :                 return NT_STATUS_OK;
     969             :         }
     970             : 
     971           0 :         if (SMB_VFS_FCHMOD(vfs->files[fd], mode) == -1) {
     972           0 :                 printf("fchmod: error=%d (%s)\n", errno, strerror(errno));
     973           0 :                 return NT_STATUS_UNSUCCESSFUL;
     974             :         }
     975             : 
     976           0 :         printf("fchmod: ok\n");
     977           0 :         return NT_STATUS_OK;
     978             : }
     979             : 
     980           0 : static NTSTATUS cmd_fchown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
     981             : {
     982             :         uid_t uid;
     983             :         gid_t gid;
     984             :         int fd;
     985           0 :         if (argc != 4) {
     986           0 :                 printf("Usage: fchown <fd> <uid> <gid>\n");
     987           0 :                 return NT_STATUS_OK;
     988             :         }
     989             : 
     990           0 :         uid = atoi(argv[2]);
     991           0 :         gid = atoi(argv[3]);
     992           0 :         fd = atoi(argv[1]);
     993           0 :         if (fd < 0 || fd >= 1024) {
     994           0 :                 printf("fchown: faliure=%d (file descriptor out of range)\n", EBADF);
     995           0 :                 return NT_STATUS_OK;
     996             :         }
     997           0 :         if (vfs->files[fd] == NULL) {
     998           0 :                 printf("fchown: error=%d (invalid file descriptor)\n", EBADF);
     999           0 :                 return NT_STATUS_OK;
    1000             :         }
    1001           0 :         if (SMB_VFS_FCHOWN(vfs->files[fd], uid, gid) == -1) {
    1002           0 :                 printf("fchown error=%d (%s)\n", errno, strerror(errno));
    1003           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1004             :         }
    1005             : 
    1006           0 :         printf("fchown: ok\n");
    1007           0 :         return NT_STATUS_OK;
    1008             : }
    1009             : 
    1010             : 
    1011           0 : static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
    1012             : {
    1013           0 :         struct smb_filename *smb_fname = SMB_VFS_GETWD(vfs->conn, talloc_tos());
    1014           0 :         if (smb_fname == NULL) {
    1015           0 :                 printf("getwd: error=%d (%s)\n", errno, strerror(errno));
    1016           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1017             :         }
    1018             : 
    1019           0 :         printf("getwd: %s\n", smb_fname->base_name);
    1020           0 :         TALLOC_FREE(smb_fname);
    1021           0 :         return NT_STATUS_OK;
    1022             : }
    1023             : 
    1024           0 : static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
    1025             : {
    1026             :         struct smb_file_time ft;
    1027           0 :         struct smb_filename *smb_fname = NULL;
    1028             :         NTSTATUS status;
    1029             : 
    1030           0 :         if (argc != 4) {
    1031           0 :                 printf("Usage: utime <path> <access> <modify>\n");
    1032           0 :                 return NT_STATUS_OK;
    1033             :         }
    1034             : 
    1035           0 :         init_smb_file_time(&ft);
    1036             : 
    1037           0 :         ft.atime = time_t_to_full_timespec(atoi(argv[2]));
    1038           0 :         ft.mtime = time_t_to_full_timespec(atoi(argv[3]));
    1039             : 
    1040           0 :         status = filename_convert(mem_ctx,
    1041           0 :                                   vfs->conn,
    1042           0 :                                   argv[1],
    1043             :                                   0,
    1044             :                                   0,
    1045             :                                   &smb_fname);
    1046           0 :         if (!NT_STATUS_IS_OK(status)) {
    1047           0 :                 printf("utime: %s\n", nt_errstr(status));
    1048           0 :                 return status;
    1049             :         }
    1050             : 
    1051           0 :         if (SMB_VFS_FNTIMES(smb_fname->fsp, &ft) != 0) {
    1052           0 :                 printf("utime: error=%d (%s)\n", errno, strerror(errno));
    1053           0 :                 TALLOC_FREE(smb_fname);
    1054           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1055             :         }
    1056             : 
    1057           0 :         TALLOC_FREE(smb_fname);
    1058           0 :         printf("utime: ok\n");
    1059           0 :         return NT_STATUS_OK;
    1060             : }
    1061             : 
    1062           0 : static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
    1063             : {
    1064             :         int fd;
    1065             :         off_t off;
    1066           0 :         if (argc != 3) {
    1067           0 :                 printf("Usage: ftruncate <fd> <length>\n");
    1068           0 :                 return NT_STATUS_OK;
    1069             :         }
    1070             : 
    1071           0 :         fd = atoi(argv[1]);
    1072           0 :         off = atoi(argv[2]);
    1073           0 :         if (fd < 0 || fd >= 1024) {
    1074           0 :                 printf("ftruncate: error=%d (file descriptor out of range)\n", EBADF);
    1075           0 :                 return NT_STATUS_OK;
    1076             :         }
    1077           0 :         if (vfs->files[fd] == NULL) {
    1078           0 :                 printf("ftruncate: error=%d (invalid file descriptor)\n", EBADF);
    1079           0 :                 return NT_STATUS_OK;
    1080             :         }
    1081             : 
    1082           0 :         if (SMB_VFS_FTRUNCATE(vfs->files[fd], off) == -1) {
    1083           0 :                 printf("ftruncate: error=%d (%s)\n", errno, strerror(errno));
    1084           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1085             :         }
    1086             : 
    1087           0 :         printf("ftruncate: ok\n");
    1088           0 :         return NT_STATUS_OK;
    1089             : }
    1090             : 
    1091           0 : static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
    1092             : {
    1093             :         int fd;
    1094             :         int op;
    1095             :         long offset;
    1096             :         long count;
    1097             :         int type;
    1098             :         const char *typestr;
    1099             : 
    1100           0 :         if (argc != 6) {
    1101           0 :                 printf("Usage: lock <fd> <op> <offset> <count> <type>\n");
    1102           0 :                 printf("  ops: G = F_GETLK\n");
    1103           0 :                 printf("       S = F_SETLK\n");
    1104           0 :                 printf("       W = F_SETLKW\n");
    1105           0 :                 printf("  type: R = F_RDLCK\n");
    1106           0 :                 printf("        W = F_WRLCK\n");
    1107           0 :                 printf("        U = F_UNLCK\n");
    1108           0 :                 return NT_STATUS_OK;
    1109             :         }
    1110             : 
    1111           0 :         if (sscanf(argv[1], "%d", &fd) == 0) {
    1112           0 :                 printf("lock: error=-1 (error parsing fd)\n");
    1113           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1114             :         }
    1115             : 
    1116           0 :         op = 0;
    1117           0 :         switch (*argv[2]) {
    1118           0 :         case 'G':
    1119           0 :                 op = F_GETLK;
    1120           0 :                 break;
    1121           0 :         case 'S':
    1122           0 :                 op = F_SETLK;
    1123           0 :                 break;
    1124           0 :         case 'W':
    1125           0 :                 op = F_SETLKW;
    1126           0 :                 break;
    1127           0 :         default:
    1128           0 :                 printf("lock: error=-1 (invalid op flag!)\n");
    1129           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1130             :         }
    1131             : 
    1132           0 :         if (sscanf(argv[3], "%ld", &offset) == 0) {
    1133           0 :                 printf("lock: error=-1 (error parsing fd)\n");
    1134           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1135             :         }
    1136             : 
    1137           0 :         if (sscanf(argv[4], "%ld", &count) == 0) {
    1138           0 :                 printf("lock: error=-1 (error parsing fd)\n");
    1139           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1140             :         }
    1141             : 
    1142           0 :         type = 0;
    1143           0 :         typestr = argv[5];
    1144           0 :         while(*typestr) {
    1145           0 :                 switch (*typestr) {
    1146           0 :                 case 'R':
    1147           0 :                         type |= F_RDLCK;
    1148           0 :                         break;
    1149           0 :                 case 'W':
    1150           0 :                         type |= F_WRLCK;
    1151           0 :                         break;
    1152           0 :                 case 'U':
    1153           0 :                         type |= F_UNLCK;
    1154           0 :                         break;
    1155           0 :                 default:
    1156           0 :                         printf("lock: error=-1 (invalid type flag!)\n");
    1157           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1158             :                 }
    1159           0 :                 typestr++;
    1160             :         }
    1161             : 
    1162           0 :         printf("lock: debug lock(fd=%d, op=%d, offset=%ld, count=%ld, type=%d))\n", fd, op, offset, count, type);
    1163             : 
    1164           0 :         if (SMB_VFS_LOCK(vfs->files[fd], op, offset, count, type) == False) {
    1165           0 :                 printf("lock: error=%d (%s)\n", errno, strerror(errno));
    1166           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1167             :         }
    1168             : 
    1169           0 :         printf("lock: ok\n");
    1170           0 :         return NT_STATUS_OK;
    1171             : }
    1172             : 
    1173           0 : static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
    1174             : {
    1175             :         int ret;
    1176           0 :         char *target = NULL;
    1177             :         struct smb_filename target_fname;
    1178           0 :         struct smb_filename *new_smb_fname = NULL;
    1179             :         NTSTATUS status;
    1180             : 
    1181           0 :         if (argc != 3) {
    1182           0 :                 printf("Usage: symlink <path> <link>\n");
    1183           0 :                 return NT_STATUS_OK;
    1184             :         }
    1185             : 
    1186           0 :         new_smb_fname = synthetic_smb_fname_split(mem_ctx,
    1187           0 :                                         argv[2],
    1188           0 :                                         lp_posix_pathnames());
    1189           0 :         if (new_smb_fname == NULL) {
    1190           0 :                 return NT_STATUS_NO_MEMORY;
    1191             :         }
    1192             : 
    1193           0 :         target = talloc_strdup(mem_ctx, argv[1]);
    1194           0 :         if (target == NULL) {
    1195           0 :                 return NT_STATUS_NO_MEMORY;
    1196             :         }
    1197             : 
    1198           0 :         target_fname = (struct smb_filename) {
    1199             :                 .base_name = target,
    1200             :         };
    1201             : 
    1202             :         /* Removes @GMT tokens if any */
    1203           0 :         status = canonicalize_snapshot_path(&target_fname, UCF_GMT_PATHNAME, 0);
    1204           0 :         if (!NT_STATUS_IS_OK(status)) {
    1205           0 :                 return status;
    1206             :         }
    1207             : 
    1208           0 :         ret = SMB_VFS_SYMLINKAT(vfs->conn,
    1209             :                         &target_fname,
    1210             :                         vfs->conn->cwd_fsp,
    1211             :                         new_smb_fname);
    1212           0 :         if (ret == -1) {
    1213           0 :                 printf("symlink: error=%d (%s)\n", errno, strerror(errno));
    1214           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1215             :         }
    1216             : 
    1217           0 :         printf("symlink: ok\n");
    1218           0 :         return NT_STATUS_OK;
    1219             : }
    1220             : 
    1221             : 
    1222           0 : static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
    1223             : {
    1224             :         char buffer[PATH_MAX];
    1225           0 :         struct smb_filename *smb_fname = NULL;
    1226             :         int size;
    1227             : 
    1228           0 :         if (argc != 2) {
    1229           0 :                 printf("Usage: readlink <path>\n");
    1230           0 :                 return NT_STATUS_OK;
    1231             :         }
    1232             : 
    1233           0 :         smb_fname = synthetic_smb_fname_split(mem_ctx,
    1234           0 :                                         argv[1],
    1235           0 :                                         lp_posix_pathnames());
    1236           0 :         if (smb_fname == NULL) {
    1237           0 :                 return NT_STATUS_NO_MEMORY;
    1238             :         }
    1239           0 :         size = SMB_VFS_READLINKAT(vfs->conn,
    1240             :                         vfs->conn->cwd_fsp,
    1241             :                         smb_fname,
    1242             :                         buffer,
    1243             :                         PATH_MAX);
    1244             : 
    1245           0 :         if (size == -1) {
    1246           0 :                 printf("readlink: error=%d (%s)\n", errno, strerror(errno));
    1247           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1248             :         }
    1249             : 
    1250           0 :         buffer[size] = '\0';
    1251           0 :         printf("readlink: %s\n", buffer);
    1252           0 :         return NT_STATUS_OK;
    1253             : }
    1254             : 
    1255             : 
    1256           0 : static NTSTATUS cmd_link(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
    1257             : {
    1258           0 :         struct smb_filename *old_smb_fname = NULL;
    1259           0 :         struct smb_filename *new_smb_fname = NULL;
    1260             :         int ret;
    1261             : 
    1262           0 :         if (argc != 3) {
    1263           0 :                 printf("Usage: link <path> <link>\n");
    1264           0 :                 return NT_STATUS_OK;
    1265             :         }
    1266             : 
    1267           0 :         old_smb_fname = synthetic_smb_fname_split(mem_ctx,
    1268           0 :                                         argv[1],
    1269           0 :                                         lp_posix_pathnames());
    1270           0 :         if (old_smb_fname == NULL) {
    1271           0 :                 return NT_STATUS_NO_MEMORY;
    1272             :         }
    1273           0 :         new_smb_fname = synthetic_smb_fname_split(mem_ctx,
    1274           0 :                                         argv[2],
    1275           0 :                                         lp_posix_pathnames());
    1276           0 :         if (new_smb_fname == NULL) {
    1277           0 :                 return NT_STATUS_NO_MEMORY;
    1278             :         }
    1279             : 
    1280           0 :         ret = SMB_VFS_LINKAT(vfs->conn,
    1281             :                         vfs->conn->cwd_fsp,
    1282             :                         old_smb_fname,
    1283             :                         vfs->conn->cwd_fsp,
    1284             :                         new_smb_fname,
    1285             :                         0);
    1286           0 :         if (ret == -1) {
    1287           0 :                 printf("link: error=%d (%s)\n", errno, strerror(errno));
    1288           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1289             :         }
    1290             : 
    1291           0 :         printf("link: ok\n");
    1292           0 :         return NT_STATUS_OK;
    1293             : }
    1294             : 
    1295           0 : static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
    1296             : {
    1297             :         mode_t mode;
    1298             :         unsigned int dev_val;
    1299             :         SMB_DEV_T dev;
    1300           0 :         struct smb_filename *smb_fname = NULL;
    1301             :         int ret;
    1302             : 
    1303           0 :         if (argc != 4) {
    1304           0 :                 printf("Usage: mknod <path> <mode> <dev>\n");
    1305           0 :                 printf("  mode is octal\n");
    1306           0 :                 printf("  dev is hex\n");
    1307           0 :                 return NT_STATUS_OK;
    1308             :         }
    1309             : 
    1310           0 :         if (sscanf(argv[2], "%ho", (unsigned short *)&mode) == 0) {
    1311           0 :                 printf("open: error=-1 (invalid mode!)\n");
    1312           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1313             :         }
    1314             : 
    1315           0 :         if (sscanf(argv[3], "%x", &dev_val) == 0) {
    1316           0 :                 printf("open: error=-1 (invalid dev!)\n");
    1317           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1318             :         }
    1319           0 :         dev = (SMB_DEV_T)dev_val;
    1320             : 
    1321           0 :         smb_fname = synthetic_smb_fname_split(mem_ctx,
    1322           0 :                                         argv[1],
    1323           0 :                                         lp_posix_pathnames());
    1324           0 :         if (smb_fname == NULL) {
    1325           0 :                 return NT_STATUS_NO_MEMORY;
    1326             :         }
    1327             : 
    1328           0 :         ret = SMB_VFS_MKNODAT(vfs->conn,
    1329             :                         vfs->conn->cwd_fsp,
    1330             :                         smb_fname,
    1331             :                         mode,
    1332             :                         dev);
    1333             : 
    1334           0 :         if (ret == -1) {
    1335           0 :                 printf("mknod: error=%d (%s)\n", errno, strerror(errno));
    1336           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1337             :         }
    1338             : 
    1339           0 :         printf("mknod: ok\n");
    1340           0 :         return NT_STATUS_OK;
    1341             : }
    1342             : 
    1343           0 : static NTSTATUS cmd_realpath(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
    1344             : {
    1345           0 :         struct smb_filename *smb_fname = NULL;
    1346             : 
    1347           0 :         if (argc != 2) {
    1348           0 :                 printf("Usage: realpath <path>\n");
    1349           0 :                 return NT_STATUS_OK;
    1350             :         }
    1351             : 
    1352           0 :         smb_fname = synthetic_smb_fname_split(mem_ctx,
    1353           0 :                                         argv[1],
    1354           0 :                                         lp_posix_pathnames());
    1355           0 :         if (smb_fname == NULL) {
    1356           0 :                 return NT_STATUS_NO_MEMORY;
    1357             :         }
    1358           0 :         if (SMB_VFS_REALPATH(vfs->conn, mem_ctx, smb_fname) == NULL) {
    1359           0 :                 printf("realpath: error=%d (%s)\n", errno, strerror(errno));
    1360           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1361             :         }
    1362             : 
    1363           0 :         printf("realpath: ok\n");
    1364           0 :         return NT_STATUS_OK;
    1365             : }
    1366             : 
    1367           0 : static NTSTATUS cmd_getxattr(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
    1368             :                              int argc, const char **argv)
    1369             : {
    1370             :         uint8_t *buf;
    1371             :         ssize_t ret;
    1372           0 :         struct smb_filename *smb_fname = NULL;
    1373           0 :         struct smb_filename *pathref_fname = NULL;
    1374             :         NTSTATUS status;
    1375             : 
    1376           0 :         if (argc != 3) {
    1377           0 :                 printf("Usage: getxattr <path> <xattr>\n");
    1378           0 :                 return NT_STATUS_OK;
    1379             :         }
    1380             : 
    1381           0 :         buf = NULL;
    1382             : 
    1383           0 :         smb_fname = synthetic_smb_fname_split(mem_ctx,
    1384           0 :                                         argv[1],
    1385           0 :                                         lp_posix_pathnames());
    1386           0 :         if (smb_fname == NULL) {
    1387           0 :                 return NT_STATUS_NO_MEMORY;
    1388             :         }
    1389           0 :         status = synthetic_pathref(mem_ctx,
    1390           0 :                                 vfs->conn->cwd_fsp,
    1391           0 :                                 smb_fname->base_name,
    1392             :                                 NULL,
    1393             :                                 NULL,
    1394             :                                 smb_fname->twrp,
    1395             :                                 smb_fname->flags,
    1396             :                                 &pathref_fname);
    1397           0 :         if (!NT_STATUS_IS_OK(status)) {
    1398           0 :                 return status;
    1399             :         }
    1400           0 :         ret = SMB_VFS_FGETXATTR(pathref_fname->fsp,
    1401             :                                 argv[2],
    1402             :                                 buf,
    1403             :                                 talloc_get_size(buf));
    1404           0 :         if (ret == -1) {
    1405           0 :                 int err = errno;
    1406           0 :                 printf("getxattr returned (%s)\n", strerror(err));
    1407           0 :                 return map_nt_error_from_unix(err);
    1408             :         }
    1409           0 :         buf = talloc_array(mem_ctx, uint8_t, ret);
    1410           0 :         if (buf == NULL) {
    1411           0 :                 return NT_STATUS_NO_MEMORY;
    1412             :         }
    1413           0 :         ret = SMB_VFS_FGETXATTR(pathref_fname->fsp,
    1414             :                                 argv[2],
    1415             :                                 buf,
    1416             :                                 talloc_get_size(buf));
    1417           0 :         if (ret == -1) {
    1418           0 :                 int err = errno;
    1419           0 :                 printf("getxattr returned (%s)\n", strerror(err));
    1420           0 :                 return map_nt_error_from_unix(err);
    1421             :         }
    1422           0 :         dump_data_file(buf, talloc_get_size(buf), false, stdout);
    1423           0 :         return NT_STATUS_OK;
    1424             : }
    1425             : 
    1426           2 : static NTSTATUS cmd_listxattr(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
    1427             :                               int argc, const char **argv)
    1428             : {
    1429             :         char *buf, *p;
    1430             :         ssize_t ret;
    1431           2 :         struct smb_filename *smb_fname = NULL;
    1432           2 :         struct smb_filename *pathref_fname = NULL;
    1433             :         NTSTATUS status;
    1434           2 :         if (argc != 2) {
    1435           0 :                 printf("Usage: listxattr <path>\n");
    1436           0 :                 return NT_STATUS_OK;
    1437             :         }
    1438             : 
    1439           2 :         buf = NULL;
    1440             : 
    1441           4 :         smb_fname = synthetic_smb_fname_split(mem_ctx,
    1442           2 :                                         argv[1],
    1443           2 :                                         lp_posix_pathnames());
    1444           2 :         if (smb_fname == NULL) {
    1445           0 :                 return NT_STATUS_NO_MEMORY;
    1446             :         }
    1447           4 :         status = synthetic_pathref(mem_ctx,
    1448           2 :                                 vfs->conn->cwd_fsp,
    1449           2 :                                 smb_fname->base_name,
    1450             :                                 NULL,
    1451             :                                 NULL,
    1452             :                                 smb_fname->twrp,
    1453             :                                 smb_fname->flags,
    1454             :                                 &pathref_fname);
    1455           2 :         if (!NT_STATUS_IS_OK(status)) {
    1456           0 :                 return status;
    1457             :         }
    1458             : 
    1459           2 :         ret = SMB_VFS_FLISTXATTR(pathref_fname->fsp,
    1460             :                                 buf, talloc_get_size(buf));
    1461           2 :         if (ret == -1) {
    1462           0 :                 int err = errno;
    1463           0 :                 printf("listxattr returned (%s)\n", strerror(err));
    1464           0 :                 return map_nt_error_from_unix(err);
    1465             :         }
    1466           2 :         buf = talloc_array(mem_ctx, char, ret);
    1467           2 :         if (buf == NULL) {
    1468           0 :                 return NT_STATUS_NO_MEMORY;
    1469             :         }
    1470           2 :         ret = SMB_VFS_FLISTXATTR(pathref_fname->fsp,
    1471             :                                 buf, talloc_get_size(buf));
    1472           2 :         if (ret == -1) {
    1473           0 :                 int err = errno;
    1474           0 :                 printf("listxattr returned (%s)\n", strerror(err));
    1475           0 :                 return map_nt_error_from_unix(err);
    1476             :         }
    1477           2 :         if (ret == 0) {
    1478           2 :                 return NT_STATUS_OK;
    1479             :         }
    1480           0 :         if (buf[ret-1] != '\0') {
    1481           0 :                 printf("listxattr returned non 0-terminated strings\n");
    1482           0 :                 return NT_STATUS_INTERNAL_ERROR;
    1483             :         }
    1484             : 
    1485           0 :         p = buf;
    1486           0 :         while (p < buf+ret) {
    1487           0 :                 printf("%s\n", p);
    1488           0 :                 p = strchr(p, 0);
    1489           0 :                 p += 1;
    1490             :         }
    1491           0 :         return NT_STATUS_OK;
    1492             : }
    1493             : 
    1494           0 : static NTSTATUS cmd_fsetxattr(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
    1495             :                              int argc, const char **argv)
    1496             : {
    1497             :         ssize_t ret;
    1498           0 :         int flags = 0;
    1499           0 :         struct smb_filename *smb_fname = NULL;
    1500           0 :         struct smb_filename *pathref_fname = NULL;
    1501             :         NTSTATUS status;
    1502             : 
    1503           0 :         if ((argc < 4) || (argc > 5)) {
    1504           0 :                 printf("Usage: setxattr <path> <xattr> <value> [flags]\n");
    1505           0 :                 return NT_STATUS_OK;
    1506             :         }
    1507             : 
    1508           0 :         if (argc == 5) {
    1509           0 :                 flags = atoi(argv[4]);
    1510             :         }
    1511             : 
    1512           0 :         smb_fname = synthetic_smb_fname_split(mem_ctx,
    1513           0 :                                         argv[1],
    1514           0 :                                         lp_posix_pathnames());
    1515           0 :         if (smb_fname == NULL) {
    1516           0 :                 return NT_STATUS_NO_MEMORY;
    1517             :         }
    1518             : 
    1519           0 :         status = synthetic_pathref(mem_ctx,
    1520           0 :                                 vfs->conn->cwd_fsp,
    1521           0 :                                 smb_fname->base_name,
    1522             :                                 NULL,
    1523             :                                 NULL,
    1524             :                                 smb_fname->twrp,
    1525             :                                 smb_fname->flags,
    1526             :                                 &pathref_fname);
    1527           0 :         if (!NT_STATUS_IS_OK(status)) {
    1528           0 :                 return status;
    1529             :         }
    1530             : 
    1531           0 :         ret = SMB_VFS_FSETXATTR(pathref_fname->fsp, argv[2],
    1532             :                                argv[3], strlen(argv[3]), flags);
    1533           0 :         if (ret == -1) {
    1534           0 :                 int err = errno;
    1535           0 :                 printf("fsetxattr returned (%s)\n", strerror(err));
    1536           0 :                 return map_nt_error_from_unix(err);
    1537             :         }
    1538           0 :         return NT_STATUS_OK;
    1539             : }
    1540             : 
    1541           0 : static NTSTATUS cmd_removexattr(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
    1542             :                                 int argc, const char **argv)
    1543             : {
    1544             :         ssize_t ret;
    1545           0 :         struct smb_filename *smb_fname = NULL;
    1546           0 :         struct smb_filename *pathref_fname = NULL;
    1547             :         NTSTATUS status;
    1548             : 
    1549           0 :         if (argc != 3) {
    1550           0 :                 printf("Usage: removexattr <path> <xattr>\n");
    1551           0 :                 return NT_STATUS_OK;
    1552             :         }
    1553             : 
    1554           0 :         smb_fname = synthetic_smb_fname_split(mem_ctx,
    1555           0 :                                         argv[1],
    1556           0 :                                         lp_posix_pathnames());
    1557           0 :         if (smb_fname == NULL) {
    1558           0 :                 return NT_STATUS_NO_MEMORY;
    1559             :         }
    1560           0 :         status = synthetic_pathref(mem_ctx,
    1561           0 :                                 vfs->conn->cwd_fsp,
    1562           0 :                                 smb_fname->base_name,
    1563             :                                 NULL,
    1564             :                                 NULL,
    1565             :                                 smb_fname->twrp,
    1566             :                                 smb_fname->flags,
    1567             :                                 &pathref_fname);
    1568           0 :         if (!NT_STATUS_IS_OK(status)) {
    1569           0 :                 return status;
    1570             :         }
    1571           0 :         ret = SMB_VFS_FREMOVEXATTR(pathref_fname->fsp, argv[2]);
    1572           0 :         if (ret == -1) {
    1573           0 :                 int err = errno;
    1574           0 :                 printf("removexattr returned (%s)\n", strerror(err));
    1575           0 :                 return map_nt_error_from_unix(err);
    1576             :         }
    1577           0 :         return NT_STATUS_OK;
    1578             : }
    1579             : 
    1580           0 : static NTSTATUS cmd_fget_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
    1581             :                                 int argc, const char **argv)
    1582             : {
    1583             :         int fd;
    1584             :         NTSTATUS status;
    1585             :         struct security_descriptor *sd;
    1586             : 
    1587           0 :         if (argc != 2) {
    1588           0 :                 printf("Usage: fget_nt_acl <fd>\n");
    1589           0 :                 return NT_STATUS_OK;
    1590             :         }
    1591             : 
    1592           0 :         fd = atoi(argv[1]);
    1593           0 :         if (fd < 0 || fd >= 1024) {
    1594           0 :                 printf("fget_nt_acl: error=%d (file descriptor out of range)\n", EBADF);
    1595           0 :                 return NT_STATUS_OK;
    1596             :         }
    1597           0 :         if (vfs->files[fd] == NULL) {
    1598           0 :                 printf("fget_nt_acl: error=%d (invalid file descriptor)\n", EBADF);
    1599           0 :                 return NT_STATUS_OK;
    1600             :         }
    1601             : 
    1602           0 :         status = SMB_VFS_FGET_NT_ACL(vfs->files[fd],
    1603             :                                      SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL,
    1604             :                                      talloc_tos(), &sd);
    1605           0 :         if (!NT_STATUS_IS_OK(status)) {
    1606           0 :                 printf("fget_nt_acl returned (%s)\n", nt_errstr(status));
    1607           0 :                 return status;
    1608             :         }
    1609           0 :         printf("%s\n", sddl_encode(talloc_tos(), sd, get_global_sam_sid()));
    1610           0 :         TALLOC_FREE(sd);
    1611           0 :         return NT_STATUS_OK;
    1612             : }
    1613             : 
    1614           8 : static NTSTATUS cmd_get_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
    1615             :                                int argc, const char **argv)
    1616             : {
    1617             :         NTSTATUS status;
    1618             :         struct security_descriptor *sd;
    1619           8 :         struct smb_filename *smb_fname = NULL;
    1620           8 :         struct smb_filename *pathref_fname = NULL;
    1621             : 
    1622           8 :         if (argc != 2) {
    1623           0 :                 printf("Usage: get_nt_acl <path>\n");
    1624           0 :                 return NT_STATUS_OK;
    1625             :         }
    1626             : 
    1627          16 :         smb_fname = synthetic_smb_fname(talloc_tos(),
    1628           8 :                                         argv[1],
    1629             :                                         NULL,
    1630             :                                         NULL,
    1631             :                                         0,
    1632             :                                         ssf_flags());
    1633             : 
    1634           8 :         if (smb_fname == NULL) {
    1635           0 :                 return NT_STATUS_NO_MEMORY;
    1636             :         }
    1637             : 
    1638          16 :         status = synthetic_pathref(mem_ctx,
    1639           8 :                                 vfs->conn->cwd_fsp,
    1640           8 :                                 smb_fname->base_name,
    1641             :                                 NULL,
    1642             :                                 NULL,
    1643             :                                 smb_fname->twrp,
    1644             :                                 smb_fname->flags,
    1645             :                                 &pathref_fname);
    1646           8 :         if (!NT_STATUS_IS_OK(status)) {
    1647           0 :                 TALLOC_FREE(smb_fname);
    1648           0 :                 return status;
    1649             :         }
    1650           8 :         status = SMB_VFS_FGET_NT_ACL(pathref_fname->fsp,
    1651             :                                 SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL,
    1652             :                                 talloc_tos(),
    1653             :                                 &sd);
    1654           8 :         if (!NT_STATUS_IS_OK(status)) {
    1655           0 :                 printf("get_nt_acl returned (%s)\n", nt_errstr(status));
    1656           0 :                 TALLOC_FREE(smb_fname);
    1657           0 :                 TALLOC_FREE(pathref_fname);
    1658           0 :                 return status;
    1659             :         }
    1660           8 :         printf("%s\n", sddl_encode(talloc_tos(), sd, get_global_sam_sid()));
    1661           8 :         TALLOC_FREE(sd);
    1662           8 :         TALLOC_FREE(smb_fname);
    1663           8 :         TALLOC_FREE(pathref_fname);
    1664           8 :         return NT_STATUS_OK;
    1665             : }
    1666             : 
    1667           0 : static NTSTATUS cmd_fset_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
    1668             :                                 int argc, const char **argv)
    1669             : {
    1670             :         int fd;
    1671             :         NTSTATUS status;
    1672             :         struct security_descriptor *sd;
    1673             : 
    1674           0 :         if (argc != 3) {
    1675           0 :                 printf("Usage: fset_nt_acl <fd> <sddl>\n");
    1676           0 :                 return NT_STATUS_OK;
    1677             :         }
    1678             : 
    1679           0 :         fd = atoi(argv[1]);
    1680           0 :         if (fd < 0 || fd >= 1024) {
    1681           0 :                 printf("fset_nt_acl: error=%d (file descriptor out of range)\n", EBADF);
    1682           0 :                 return NT_STATUS_OK;
    1683             :         }
    1684           0 :         if (vfs->files[fd] == NULL) {
    1685           0 :                 printf("fset_nt_acl: error=%d (invalid file descriptor)\n", EBADF);
    1686           0 :                 return NT_STATUS_OK;
    1687             :         }
    1688             : 
    1689           0 :         sd = sddl_decode(talloc_tos(), argv[2], get_global_sam_sid());
    1690           0 :         if (!sd) {
    1691           0 :                 printf("sddl_decode failed to parse %s as SDDL\n", argv[2]);
    1692           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1693             :         }
    1694             : 
    1695           0 :         status = SMB_VFS_FSET_NT_ACL(vfs->files[fd], SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL, sd);
    1696           0 :         if (!NT_STATUS_IS_OK(status)) {
    1697           0 :                 printf("fset_nt_acl returned (%s)\n", nt_errstr(status));
    1698           0 :                 return status;
    1699             :         }
    1700           0 :         TALLOC_FREE(sd);
    1701           0 :         return NT_STATUS_OK;
    1702             : }
    1703             : 
    1704           4 : static NTSTATUS cmd_set_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
    1705             : {
    1706             :         int flags;
    1707             :         int ret;
    1708             :         mode_t mode;
    1709             :         files_struct *fsp;
    1710           4 :         struct files_struct *fspcwd = NULL;
    1711           4 :         struct smb_filename *smb_fname = NULL;
    1712             :         NTSTATUS status;
    1713           4 :         struct security_descriptor *sd = NULL;
    1714             :         int fd;
    1715             : 
    1716           4 :         if (argc != 3) {
    1717           0 :                 printf("Usage: set_nt_acl <file> <sddl>\n");
    1718           0 :                 return NT_STATUS_OK;
    1719             :         }
    1720             : 
    1721           4 :         mode = 00400;
    1722             : 
    1723           4 :         fsp = talloc_zero(vfs, struct files_struct);
    1724           4 :         if (fsp == NULL) {
    1725           0 :                 return NT_STATUS_NO_MEMORY;
    1726             :         }
    1727           4 :         fsp->fh = fd_handle_create(fsp);
    1728           4 :         if (fsp->fh == NULL) {
    1729           0 :                 TALLOC_FREE(fsp);
    1730           0 :                 return NT_STATUS_NO_MEMORY;
    1731             :         }
    1732           4 :         fsp->conn = vfs->conn;
    1733             : 
    1734           8 :         smb_fname = synthetic_smb_fname_split(NULL,
    1735           4 :                                         argv[1],
    1736           4 :                                         lp_posix_pathnames());
    1737           4 :         if (smb_fname == NULL) {
    1738           0 :                 TALLOC_FREE(fsp);
    1739           0 :                 return NT_STATUS_NO_MEMORY;
    1740             :         }
    1741             : 
    1742           4 :         fsp->fsp_name = smb_fname;
    1743             : 
    1744             : #ifdef O_DIRECTORY
    1745           4 :         flags = O_RDONLY|O_DIRECTORY;
    1746             : #else
    1747             :         /* POSIX allows us to open a directory with O_RDONLY. */
    1748             :         flags = O_RDONLY;
    1749             : #endif
    1750             : 
    1751           4 :         status = vfs_at_fspcwd(fsp, vfs->conn, &fspcwd);
    1752           4 :         if (!NT_STATUS_IS_OK(status)) {
    1753           0 :                 return status;
    1754             :         }
    1755             : 
    1756           4 :         fd = SMB_VFS_OPENAT(vfs->conn,
    1757             :                             fspcwd,
    1758             :                             smb_fname,
    1759             :                             fsp,
    1760             :                             O_RDWR,
    1761             :                             mode);
    1762           4 :         if (fd == -1 && errno == EISDIR) {
    1763           2 :                 fd = SMB_VFS_OPENAT(vfs->conn,
    1764             :                                     fspcwd,
    1765             :                                     smb_fname,
    1766             :                                     fsp,
    1767             :                                     flags,
    1768             :                                     mode);
    1769             :         }
    1770           4 :         if (fd == -1) {
    1771           0 :                 printf("open: error=%d (%s)\n", errno, strerror(errno));
    1772           0 :                 TALLOC_FREE(fsp);
    1773           0 :                 TALLOC_FREE(smb_fname);
    1774           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1775             :         }
    1776           4 :         fsp_set_fd(fsp, fd);
    1777             : 
    1778           4 :         status = NT_STATUS_OK;
    1779           4 :         ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
    1780           4 :         if (ret == -1) {
    1781             :                 /* If we have an fd, this stat should succeed. */
    1782           0 :                 DEBUG(0,("Error doing fstat on open file %s "
    1783             :                          "(%s)\n",
    1784             :                          smb_fname_str_dbg(smb_fname),
    1785             :                          strerror(errno) ));
    1786           0 :                 status = map_nt_error_from_unix(errno);
    1787             :         }
    1788             :         
    1789           4 :         if (!NT_STATUS_IS_OK(status)) {
    1790           0 :                 goto out;
    1791             :         }
    1792             : 
    1793           4 :         fsp->file_id = vfs_file_id_from_sbuf(vfs->conn, &smb_fname->st);
    1794           4 :         fsp->vuid = UID_FIELD_INVALID;
    1795           4 :         fsp->file_pid = 0;
    1796           4 :         fsp->fsp_flags.can_lock = true;
    1797           4 :         fsp->fsp_flags.can_read = true;
    1798           4 :         fsp->fsp_flags.can_write = true;
    1799           4 :         fsp->print_file = NULL;
    1800           4 :         fsp->fsp_flags.modified = false;
    1801           4 :         fsp->sent_oplock_break = NO_BREAK_SENT;
    1802           4 :         fsp->fsp_flags.is_directory = S_ISDIR(smb_fname->st.st_ex_mode);
    1803             : 
    1804           4 :         sd = sddl_decode(talloc_tos(), argv[2], get_global_sam_sid());
    1805           4 :         if (!sd) {
    1806           0 :                 printf("sddl_decode failed to parse %s as SDDL\n", argv[2]);
    1807           0 :                 status = NT_STATUS_INVALID_PARAMETER;
    1808           0 :                 goto out;
    1809             :         }
    1810             : 
    1811           4 :         status = SMB_VFS_FSET_NT_ACL(fsp, SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL, sd);
    1812           4 :         if (!NT_STATUS_IS_OK(status)) {
    1813           0 :                 printf("fset_nt_acl returned (%s)\n", nt_errstr(status));
    1814           0 :                 goto out;
    1815             :         }
    1816           8 : out:
    1817           4 :         TALLOC_FREE(sd);
    1818             : 
    1819           4 :         ret = SMB_VFS_CLOSE(fsp);
    1820           4 :         if (ret == -1 )
    1821           0 :                 printf("close: error=%d (%s)\n", errno, strerror(errno));
    1822             : 
    1823           4 :         TALLOC_FREE(fsp);
    1824             : 
    1825           4 :         return status;
    1826             : }
    1827             : 
    1828             : 
    1829             : 
    1830           0 : static NTSTATUS cmd_sys_acl_get_fd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
    1831             :                                    int argc, const char **argv)
    1832             : {
    1833             :         int fd;
    1834             :         SMB_ACL_T acl;
    1835             :         char *acl_text;
    1836             : 
    1837           0 :         if (argc != 2) {
    1838           0 :                 printf("Usage: sys_acl_get_fd <fd>\n");
    1839           0 :                 return NT_STATUS_OK;
    1840             :         }
    1841             : 
    1842           0 :         fd = atoi(argv[1]);
    1843           0 :         if (fd < 0 || fd >= 1024) {
    1844           0 :                 printf("sys_acl_get_fd: error=%d (file descriptor out of range)\n", EBADF);
    1845           0 :                 return NT_STATUS_OK;
    1846             :         }
    1847           0 :         if (vfs->files[fd] == NULL) {
    1848           0 :                 printf("sys_acl_get_fd: error=%d (invalid file descriptor)\n", EBADF);
    1849           0 :                 return NT_STATUS_OK;
    1850             :         }
    1851             : 
    1852           0 :         acl = SMB_VFS_SYS_ACL_GET_FD(vfs->files[fd],
    1853             :                                      SMB_ACL_TYPE_ACCESS,
    1854             :                                      talloc_tos());
    1855           0 :         if (!acl) {
    1856           0 :                 printf("sys_acl_get_fd failed (%s)\n", strerror(errno));
    1857           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1858             :         }
    1859           0 :         acl_text = sys_acl_to_text(acl, NULL);
    1860           0 :         printf("%s", acl_text);
    1861           0 :         TALLOC_FREE(acl);
    1862           0 :         SAFE_FREE(acl_text);
    1863           0 :         return NT_STATUS_OK;
    1864             : }
    1865             : 
    1866          12 : static NTSTATUS cmd_sys_acl_get_file(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
    1867             :                                      int argc, const char **argv)
    1868             : {
    1869             :         SMB_ACL_T acl;
    1870             :         char *acl_text;
    1871             :         int type;
    1872          12 :         struct smb_filename *smb_fname = NULL;
    1873          12 :         struct smb_filename *pathref_fname = NULL;
    1874             :         NTSTATUS status;
    1875             : 
    1876          12 :         if (argc != 3) {
    1877           0 :                 printf("Usage: sys_acl_get_file <path> <type>\n");
    1878           0 :                 return NT_STATUS_OK;
    1879             :         }
    1880             : 
    1881          24 :         smb_fname = synthetic_smb_fname_split(talloc_tos(),
    1882          12 :                                         argv[1],
    1883          12 :                                         lp_posix_pathnames());
    1884          12 :         if (smb_fname == NULL) {
    1885           0 :                 return NT_STATUS_NO_MEMORY;
    1886             :         }
    1887          12 :         type = atoi(argv[2]);
    1888             : 
    1889          24 :         status = synthetic_pathref(mem_ctx,
    1890          12 :                                 vfs->conn->cwd_fsp,
    1891          12 :                                 smb_fname->base_name,
    1892             :                                 NULL,
    1893             :                                 NULL,
    1894             :                                 smb_fname->twrp,
    1895             :                                 smb_fname->flags,
    1896             :                                 &pathref_fname);
    1897          12 :         if (!NT_STATUS_IS_OK(status)) {
    1898           0 :                 TALLOC_FREE(smb_fname);
    1899           0 :                 return status;
    1900             :         }
    1901             : 
    1902          12 :         acl = SMB_VFS_SYS_ACL_GET_FD(pathref_fname->fsp,
    1903             :                                 type, talloc_tos());
    1904          12 :         if (!acl) {
    1905           6 :                 printf("sys_acl_get_fd failed (%s)\n", strerror(errno));
    1906           6 :                 TALLOC_FREE(smb_fname);
    1907           6 :                 TALLOC_FREE(pathref_fname);
    1908           6 :                 return NT_STATUS_UNSUCCESSFUL;
    1909             :         }
    1910           6 :         acl_text = sys_acl_to_text(acl, NULL);
    1911           6 :         printf("%s", acl_text);
    1912           6 :         TALLOC_FREE(acl);
    1913           6 :         TALLOC_FREE(smb_fname);
    1914           6 :         TALLOC_FREE(pathref_fname);
    1915           6 :         SAFE_FREE(acl_text);
    1916           6 :         return NT_STATUS_OK;
    1917             : }
    1918             : 
    1919           0 : static NTSTATUS cmd_sys_acl_blob_get_file(struct vfs_state *vfs,
    1920             :                                           TALLOC_CTX *mem_ctx,
    1921             :                                           int argc, const char **argv)
    1922             : {
    1923             :         char *description;
    1924             :         DATA_BLOB blob;
    1925             :         int ret;
    1926             :         size_t i;
    1927           0 :         struct smb_filename *smb_fname = NULL;
    1928           0 :         struct smb_filename *pathref_fname = NULL;
    1929             :         NTSTATUS status;
    1930             : 
    1931           0 :         if (argc != 2) {
    1932           0 :                 printf("Usage: sys_acl_blob_get_file <path>\n");
    1933           0 :                 return NT_STATUS_OK;
    1934             :         }
    1935             : 
    1936           0 :         smb_fname = synthetic_smb_fname_split(mem_ctx,
    1937           0 :                                         argv[1],
    1938           0 :                                         lp_posix_pathnames());
    1939           0 :         if (smb_fname == NULL) {
    1940           0 :                 return NT_STATUS_NO_MEMORY;
    1941             :         }
    1942           0 :         status = synthetic_pathref(mem_ctx,
    1943           0 :                                 vfs->conn->cwd_fsp,
    1944           0 :                                 smb_fname->base_name,
    1945             :                                 NULL,
    1946             :                                 NULL,
    1947             :                                 smb_fname->twrp,
    1948             :                                 smb_fname->flags,
    1949             :                                 &pathref_fname);
    1950           0 :         if (!NT_STATUS_IS_OK(status)) {
    1951           0 :                 TALLOC_FREE(smb_fname);
    1952           0 :                 return status;
    1953             :         }
    1954             : 
    1955           0 :         ret = SMB_VFS_SYS_ACL_BLOB_GET_FD(pathref_fname->fsp,
    1956             :                                           talloc_tos(),
    1957             :                                           &description,
    1958             :                                           &blob);
    1959           0 :         if (ret != 0) {
    1960           0 :                 status = map_nt_error_from_unix(errno);
    1961           0 :                 printf("sys_acl_blob_get_file failed (%s)\n", strerror(errno));
    1962           0 :                 TALLOC_FREE(smb_fname);
    1963           0 :                 TALLOC_FREE(pathref_fname);
    1964           0 :                 return status;
    1965             :         }
    1966           0 :         printf("Description: %s\n", description);
    1967           0 :         for (i = 0; i < blob.length; i++) {
    1968           0 :                 printf("%.2x ", blob.data[i]);
    1969             :         }
    1970           0 :         printf("\n");
    1971             : 
    1972           0 :         TALLOC_FREE(smb_fname);
    1973           0 :         TALLOC_FREE(pathref_fname);
    1974           0 :         return NT_STATUS_OK;
    1975             : }
    1976             : 
    1977           0 : static NTSTATUS cmd_sys_acl_blob_get_fd(struct vfs_state *vfs,
    1978             :                                         TALLOC_CTX *mem_ctx,
    1979             :                                         int argc, const char **argv)
    1980             : {
    1981             :         int fd;
    1982             :         char *description;
    1983             :         DATA_BLOB blob;
    1984             :         int ret;
    1985             :         size_t i;
    1986             : 
    1987           0 :         if (argc != 2) {
    1988           0 :                 printf("Usage: sys_acl_blob_get_fd <fd>\n");
    1989           0 :                 return NT_STATUS_OK;
    1990             :         }
    1991             : 
    1992           0 :         fd = atoi(argv[1]);
    1993           0 :         if (fd < 0 || fd >= 1024) {
    1994           0 :                 printf("sys_acl_blob_get_fd: error=%d "
    1995             :                        "(file descriptor out of range)\n", EBADF);
    1996           0 :                 return NT_STATUS_OK;
    1997             :         }
    1998           0 :         if (vfs->files[fd] == NULL) {
    1999           0 :                 printf("sys_acl_blob_get_fd: error=%d "
    2000             :                        "(invalid file descriptor)\n", EBADF);
    2001           0 :                 return NT_STATUS_OK;
    2002             :         }
    2003             : 
    2004           0 :         ret = SMB_VFS_SYS_ACL_BLOB_GET_FD(vfs->files[fd], talloc_tos(),
    2005             :                                           &description, &blob);
    2006           0 :         if (ret != 0) {
    2007           0 :                 printf("sys_acl_blob_get_fd failed (%s)\n", strerror(errno));
    2008           0 :                 return map_nt_error_from_unix(errno);
    2009             :         }
    2010           0 :         printf("Description: %s\n", description);
    2011           0 :         for (i = 0; i < blob.length; i++) {
    2012           0 :                 printf("%.2x ", blob.data[i]);
    2013             :         }
    2014           0 :         printf("\n");
    2015             : 
    2016           0 :         return NT_STATUS_OK;
    2017             : }
    2018             : 
    2019             : 
    2020             : 
    2021           0 : static NTSTATUS cmd_sys_acl_delete_def_file(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
    2022             :                                             int argc, const char **argv)
    2023             : {
    2024             :         int ret;
    2025           0 :         struct smb_filename *smb_fname = NULL;
    2026           0 :         struct smb_filename *pathref_fname = NULL;
    2027             :         NTSTATUS status;
    2028             : 
    2029           0 :         if (argc != 2) {
    2030           0 :                 printf("Usage: sys_acl_delete_def_file <path>\n");
    2031           0 :                 return NT_STATUS_OK;
    2032             :         }
    2033             : 
    2034           0 :         smb_fname = synthetic_smb_fname_split(mem_ctx,
    2035           0 :                                         argv[1],
    2036           0 :                                         lp_posix_pathnames());
    2037           0 :         if (smb_fname == NULL) {
    2038           0 :                 return NT_STATUS_NO_MEMORY;
    2039             :         }
    2040           0 :         status = synthetic_pathref(mem_ctx,
    2041           0 :                                 vfs->conn->cwd_fsp,
    2042           0 :                                 smb_fname->base_name,
    2043             :                                 NULL,
    2044             :                                 NULL,
    2045             :                                 smb_fname->twrp,
    2046             :                                 smb_fname->flags,
    2047             :                                 &pathref_fname);
    2048           0 :         if (!NT_STATUS_IS_OK(status)) {
    2049           0 :                 TALLOC_FREE(smb_fname);
    2050           0 :                 return status;
    2051             :         }
    2052           0 :         if (!pathref_fname->fsp->fsp_flags.is_directory) {
    2053           0 :                 printf("sys_acl_delete_def_file - %s is not a directory\n",
    2054             :                         smb_fname->base_name);
    2055           0 :                 TALLOC_FREE(smb_fname);
    2056           0 :                 TALLOC_FREE(pathref_fname);
    2057           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2058             :         }
    2059           0 :         ret = SMB_VFS_SYS_ACL_DELETE_DEF_FD(pathref_fname->fsp);
    2060           0 :         if (ret == -1) {
    2061           0 :                 int err = errno;
    2062           0 :                 printf("sys_acl_delete_def_file failed (%s)\n", strerror(err));
    2063           0 :                 TALLOC_FREE(smb_fname);
    2064           0 :                 TALLOC_FREE(pathref_fname);
    2065           0 :                 return map_nt_error_from_unix(err);
    2066             :         }
    2067           0 :         TALLOC_FREE(smb_fname);
    2068           0 :         TALLOC_FREE(pathref_fname);
    2069           0 :         return NT_STATUS_OK;
    2070             : }
    2071             : 
    2072             : /* Afaik translate name was first introduced with vfs_catia, to be able
    2073             :    to translate unix file/dir-names, containing invalid windows characters,
    2074             :    to valid windows names.
    2075             :    The used translation direction is always unix --> windows
    2076             : */
    2077           2 : static NTSTATUS cmd_translate_name(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
    2078             :                                             int argc, const char **argv)
    2079             : {
    2080           2 :         const char *dname = NULL;
    2081           2 :         char *dname_talloced = NULL;
    2082             :         SMB_STRUCT_STAT st;
    2083           2 :         bool found = false;
    2084           2 :         char *translated = NULL;
    2085           2 :         struct smb_filename *smb_fname = NULL;
    2086             :         NTSTATUS status;
    2087             : 
    2088           2 :         if (argc != 2) {
    2089           0 :                 DEBUG(0, ("Usage: translate_name unix_filename\n"));
    2090           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2091             :         }
    2092             : 
    2093           2 :         smb_fname = synthetic_smb_fname(talloc_tos(),
    2094             :                                         ".",
    2095             :                                         NULL,
    2096             :                                         NULL,
    2097             :                                         0,
    2098             :                                         ssf_flags());
    2099           2 :         if (smb_fname == NULL) {
    2100           0 :                 return NT_STATUS_NO_MEMORY;
    2101             :         }
    2102             : 
    2103           2 :         vfs->currentdir = OpenDir(talloc_tos(),
    2104           2 :                                   vfs->conn,
    2105             :                                   smb_fname,
    2106             :                                   NULL,
    2107             :                                   0);
    2108           2 :         if (vfs->currentdir == NULL) {
    2109           0 :                 DEBUG(0, ("cmd_translate_name: opendir error=%d (%s)\n",
    2110             :                           errno, strerror(errno)));
    2111           0 :                 TALLOC_FREE(smb_fname);
    2112           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2113             :         }
    2114           2 :         vfs->currentdir_offset = 0;
    2115             : 
    2116             :         while (true) {
    2117             :                 /* ReadDirName() returns Windows "encoding" */
    2118          10 :                 dname = ReadDirName(vfs->currentdir,
    2119             :                                     &vfs->currentdir_offset,
    2120             :                                     &st,
    2121             :                                     &dname_talloced);
    2122           6 :                 if (dname == NULL) {
    2123           0 :                         break;
    2124             :                 }
    2125             : 
    2126             :                 /* Convert Windows "encoding" from ReadDirName() to UNIX */
    2127           6 :                 status = SMB_VFS_TRANSLATE_NAME(vfs->conn,
    2128             :                                                 dname,
    2129             :                                                 vfs_translate_to_unix,
    2130             :                                                 talloc_tos(),
    2131             :                                                 &translated);
    2132           6 :                 if (!NT_STATUS_IS_OK(status)) {
    2133           0 :                         DBG_ERR("file '%s' cannot be translated\n", argv[1]);
    2134           0 :                         goto cleanup;
    2135             :                 }
    2136             : 
    2137             :                 /*
    2138             :                  * argv[1] uses UNIX "encoding", so compare with translation
    2139             :                  * result.
    2140             :                  */
    2141           6 :                 if (strcmp(translated, argv[1]) == 0) {
    2142           2 :                         found = true;
    2143           2 :                         break;
    2144             :                 }
    2145           4 :                 TALLOC_FREE(dname_talloced);
    2146           4 :                 TALLOC_FREE(translated);
    2147             :         };
    2148             : 
    2149           2 :         if (!found) {
    2150           0 :                 DEBUG(0, ("cmd_translate_name: file '%s' not found.\n", 
    2151             :                           argv[1]));
    2152           0 :                 status = NT_STATUS_UNSUCCESSFUL;
    2153           0 :                 goto cleanup;
    2154             :         }
    2155             : 
    2156             :         /* translation success. But that could also mean
    2157             :            that translating "aaa" to "aaa" was successful :-(
    2158             :         */ 
    2159           2 :         DBG_ERR("file '%s' --> '%s'\n", argv[1], dname);
    2160           2 :         status = NT_STATUS_OK;
    2161             : 
    2162           2 : cleanup:
    2163           2 :         TALLOC_FREE(dname_talloced);
    2164           2 :         TALLOC_FREE(translated);
    2165           2 :         TALLOC_FREE(smb_fname);
    2166           2 :         TALLOC_FREE(vfs->currentdir);
    2167           2 :         vfs->currentdir_offset = 0;
    2168           2 :         return status;
    2169             : }
    2170             : 
    2171             : 
    2172             : struct cmd_set vfs_commands[] = {
    2173             : 
    2174             :         { .name = "VFS Commands" },
    2175             : 
    2176             :         { "load", cmd_load_module, "Load a module", "load <module.so>" },
    2177             :         { "populate", cmd_populate, "Populate a data buffer", "populate <char> <size>" },
    2178             :         { "showdata", cmd_show_data, "Show data currently in data buffer", "show_data [<offset> <len>]"},
    2179             :         { "connect",   cmd_connect,   "VFS connect()",    "connect" },
    2180             :         { "disconnect",   cmd_disconnect,   "VFS disconnect()",    "disconnect" },
    2181             :         { "disk_free",   cmd_disk_free,   "VFS disk_free()",    "disk_free <path>" },
    2182             :         { "opendir",   cmd_opendir,   "VFS opendir()",    "opendir <fname>" },
    2183             :         { "readdir",   cmd_readdir,   "VFS readdir()",    "readdir" },
    2184             :         { "mkdir",   cmd_mkdir,   "VFS mkdir()",    "mkdir <path>" },
    2185             :         { "rmdir",   cmd_pathfunc,   "VFS rmdir()",    "rmdir <path>" },
    2186             :         { "closedir",   cmd_closedir,   "VFS closedir()",    "closedir" },
    2187             :         { "open",   cmd_open,   "VFS open()",    "open <fname> <flags> <mode>" },
    2188             :         { "close",   cmd_close,   "VFS close()",    "close <fd>" },
    2189             :         { "read",   cmd_read,   "VFS read()",    "read <fd> <size>" },
    2190             :         { "write",   cmd_write,   "VFS write()",    "write <fd> <size>" },
    2191             :         { "lseek",   cmd_lseek,   "VFS lseek()",    "lseek <fd> <offset> <whence>" },
    2192             :         { "rename",   cmd_rename,   "VFS rename()",    "rename <old> <new>" },
    2193             :         { "fsync",   cmd_fsync,   "VFS fsync()",    "fsync <fd>" },
    2194             :         { "stat",   cmd_stat,   "VFS stat()",    "stat <fname>" },
    2195             :         { "fstat",   cmd_fstat,   "VFS fstat()",    "fstat <fd>" },
    2196             :         { "lstat",   cmd_lstat,   "VFS lstat()",    "lstat <fname>" },
    2197             :         { "unlink",   cmd_pathfunc,   "VFS unlink()",    "unlink <fname>" },
    2198             :         { "chmod",   cmd_chmod,   "VFS chmod()",    "chmod <path> <mode>" },
    2199             :         { "fchmod",   cmd_fchmod,   "VFS fchmod()",    "fchmod <fd> <mode>" },
    2200             :         { "fchown",   cmd_fchown,   "VFS fchown()",    "fchown <fd> <uid> <gid>" },
    2201             :         { "chdir",   cmd_pathfunc,   "VFS chdir()",    "chdir <path>" },
    2202             :         { "getwd",   cmd_getwd,   "VFS getwd()",    "getwd" },
    2203             :         { "utime",   cmd_utime,   "VFS utime()",    "utime <path> <access> <modify>" },
    2204             :         { "ftruncate",   cmd_ftruncate,   "VFS ftruncate()",    "ftruncate <fd> <length>" },
    2205             :         { "lock",   cmd_lock,   "VFS lock()",    "lock <f> <op> <offset> <count> <type>" },
    2206             :         { "symlink",   cmd_symlink,   "VFS symlink()",    "symlink <old> <new>" },
    2207             :         { "readlink",   cmd_readlink,   "VFS readlink()",    "readlink <path>" },
    2208             :         { "link",   cmd_link,   "VFS link()",    "link <oldpath> <newpath>" },
    2209             :         { "mknod",   cmd_mknod,   "VFS mknod()",    "mknod <path> <mode> <dev>" },
    2210             :         { "realpath",   cmd_realpath,   "VFS realpath()",    "realpath <path>" },
    2211             :         { "getxattr", cmd_getxattr, "VFS getxattr()",
    2212             :           "getxattr <path> <name>" },
    2213             :         { "listxattr", cmd_listxattr, "VFS listxattr()",
    2214             :           "listxattr <path>" },
    2215             :         { "fsetxattr", cmd_fsetxattr, "VFS fsetxattr()",
    2216             :           "fsetxattr <path> <name> <value> [<flags>]" },
    2217             :         { "removexattr", cmd_removexattr, "VFS removexattr()",
    2218             :           "removexattr <path> <name>\n" },
    2219             :         { "fget_nt_acl", cmd_fget_nt_acl, "VFS fget_nt_acl()", 
    2220             :           "fget_nt_acl <fd>\n" },
    2221             :         { "get_nt_acl", cmd_get_nt_acl, "VFS get_nt_acl()", 
    2222             :           "get_nt_acl <path>\n" },
    2223             :         { "fset_nt_acl", cmd_fset_nt_acl, "VFS fset_nt_acl()", 
    2224             :           "fset_nt_acl <fd>\n" },
    2225             :         { "set_nt_acl", cmd_set_nt_acl, "VFS open() and fset_nt_acl()", 
    2226             :           "set_nt_acl <file>\n" },
    2227             :         { "sys_acl_get_file", cmd_sys_acl_get_file, "VFS sys_acl_get_file()", "sys_acl_get_file <path>" },
    2228             :         { "sys_acl_get_fd", cmd_sys_acl_get_fd, "VFS sys_acl_get_fd()", "sys_acl_get_fd <fd>" },
    2229             :         { "sys_acl_blob_get_file", cmd_sys_acl_blob_get_file,
    2230             :           "VFS sys_acl_blob_get_file()", "sys_acl_blob_get_file <path>" },
    2231             :         { "sys_acl_blob_get_fd", cmd_sys_acl_blob_get_fd,
    2232             :           "VFS sys_acl_blob_get_fd()", "sys_acl_blob_get_fd <path>" },
    2233             :         { "sys_acl_delete_def_file", cmd_sys_acl_delete_def_file, "VFS sys_acl_delete_def_file()", "sys_acl_delete_def_file <path>" },
    2234             : 
    2235             : 
    2236             :         { "test_chain", cmd_test_chain, "test chain code",
    2237             :           "test_chain" },
    2238             :         { "translate_name", cmd_translate_name, "VFS translate_name()", "translate_name unix_filename" },
    2239             :         {0}
    2240             : };

Generated by: LCOV version 1.13