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