LCOV - code coverage report
Current view: top level - source3/torture - cmd_vfs.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 295 1273 23.2 %
Date: 2024-04-21 15:09:00 Functions: 13 49 26.5 %

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

Generated by: LCOV version 1.14