smbd: use fh_[get|set]_pos() and fh_[get|set]_position_information()
[samba.git] / source3 / smbd / trans2.c
1 /*
2    Unix SMB/CIFS implementation.
3    SMB transaction2 handling
4    Copyright (C) Jeremy Allison                 1994-2007
5    Copyright (C) Stefan (metze) Metzmacher      2003
6    Copyright (C) Volker Lendecke                2005-2007
7    Copyright (C) Steve French                   2005
8    Copyright (C) James Peach                    2006-2007
9
10    Extensively modified by Andrew Tridgell, 1995
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 3 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include "includes.h"
27 #include "ntioctl.h"
28 #include "system/filesys.h"
29 #include "lib/util/time_basic.h"
30 #include "version.h"
31 #include "smbd/smbd.h"
32 #include "smbd/globals.h"
33 #include "../libcli/auth/libcli_auth.h"
34 #include "../librpc/gen_ndr/xattr.h"
35 #include "../librpc/gen_ndr/ndr_security.h"
36 #include "libcli/security/security.h"
37 #include "trans2.h"
38 #include "auth.h"
39 #include "smbprofile.h"
40 #include "rpc_server/srv_pipe_hnd.h"
41 #include "printing.h"
42 #include "lib/util_ea.h"
43 #include "lib/readdir_attr.h"
44 #include "messages.h"
45 #include "smb1_utils.h"
46 #include "libcli/smb/smb2_posix.h"
47 #include "lib/util/string_wrappers.h"
48
49 #define DIR_ENTRY_SAFETY_MARGIN 4096
50
51 static char *store_file_unix_basic(connection_struct *conn,
52                                 char *pdata,
53                                 files_struct *fsp,
54                                 const SMB_STRUCT_STAT *psbuf);
55
56 static char *store_file_unix_basic_info2(connection_struct *conn,
57                                 char *pdata,
58                                 files_struct *fsp,
59                                 const SMB_STRUCT_STAT *psbuf);
60
61 /****************************************************************************
62  Check if an open file handle or smb_fname is a symlink.
63 ****************************************************************************/
64
65 static NTSTATUS refuse_symlink(connection_struct *conn,
66                         const files_struct *fsp,
67                         const struct smb_filename *smb_fname)
68 {
69         SMB_STRUCT_STAT sbuf;
70         const SMB_STRUCT_STAT *pst = NULL;
71
72         if (fsp) {
73                 pst = &fsp->fsp_name->st;
74         } else {
75                 pst = &smb_fname->st;
76         }
77
78         if (!VALID_STAT(*pst)) {
79                 int ret = vfs_stat_smb_basename(conn,
80                                 smb_fname,
81                                 &sbuf);
82                 if (ret == -1 && errno != ENOENT) {
83                         return map_nt_error_from_unix(errno);
84                 } else if (ret == -1) {
85                         /* it's not a symlink.. */
86                         return NT_STATUS_OK;
87                 }
88                 pst = &sbuf;
89         }
90
91         if (S_ISLNK(pst->st_ex_mode)) {
92                 return NT_STATUS_ACCESS_DENIED;
93         }
94         return NT_STATUS_OK;
95 }
96
97 NTSTATUS check_access_fsp(const struct files_struct *fsp,
98                           uint32_t access_mask)
99 {
100         if (!(fsp->access_mask & access_mask)) {
101                 return NT_STATUS_ACCESS_DENIED;
102         }
103         return NT_STATUS_OK;
104 }
105
106 #if defined(HAVE_POSIX_ACLS)
107 /****************************************************************************
108  Utility function to open a fsp for a POSIX handle operation.
109 ****************************************************************************/
110
111 static NTSTATUS get_posix_fsp(connection_struct *conn,
112                         struct smb_request *req,
113                         const struct smb_filename *smb_fname,
114                         uint32_t access_mask,
115                         files_struct **ret_fsp)
116 {
117         NTSTATUS status;
118         struct smb_filename *smb_fname_tmp = NULL;
119         uint32_t create_disposition = FILE_OPEN;
120         uint32_t share_access = FILE_SHARE_READ|
121                                 FILE_SHARE_WRITE|
122                                 FILE_SHARE_DELETE;
123         struct smb2_create_blobs *posx = NULL;
124
125         /*
126          * Only FILE_FLAG_POSIX_SEMANTICS matters on existing files,
127          * but set reasonable defaults.
128          */
129         uint32_t file_attributes = 0664;
130         uint32_t oplock = NO_OPLOCK;
131         uint32_t create_options = FILE_NON_DIRECTORY_FILE;
132
133         /* File or directory must exist. */
134         if (!VALID_STAT(smb_fname->st)) {
135                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
136         }
137         /* Cannot be a symlink. */
138         if (S_ISLNK(smb_fname->st.st_ex_mode)) {
139                 return NT_STATUS_ACCESS_DENIED;
140         }
141         /* Set options correctly for directory open. */
142         if (S_ISDIR(smb_fname->st.st_ex_mode)) {
143                 /*
144                  * Only FILE_FLAG_POSIX_SEMANTICS matters on existing
145                  * directories, but set reasonable defaults.
146                  */
147                 file_attributes = 0775;
148                 create_options = FILE_DIRECTORY_FILE;
149         }
150
151         /* Createfile uses a non-const smb_fname. */
152         smb_fname_tmp = cp_smb_filename(talloc_tos(),
153                                         smb_fname);
154         if (smb_fname_tmp == NULL) {
155                 status = NT_STATUS_NO_MEMORY;
156                 goto done;
157         }
158
159         status = make_smb2_posix_create_ctx(
160                 talloc_tos(), &posx, file_attributes);
161         if (!NT_STATUS_IS_OK(status)) {
162                 DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
163                             nt_errstr(status));
164                 goto done;
165         }
166
167         status = SMB_VFS_CREATE_FILE(
168                 conn,           /* conn */
169                 req,            /* req */
170                 smb_fname_tmp,  /* fname */
171                 access_mask,    /* access_mask */
172                 share_access,   /* share_access */
173                 create_disposition,/* create_disposition*/
174                 create_options, /* create_options */
175                 file_attributes,/* file_attributes */
176                 oplock,         /* oplock_request */
177                 NULL,           /* lease */
178                 0,              /* allocation_size */
179                 0,              /* private_flags */
180                 NULL,           /* sd */
181                 NULL,           /* ea_list */
182                 ret_fsp,        /* result */
183                 NULL,           /* pinfo */
184                 posx,           /* in_context */
185                 NULL);          /* out_context */
186
187 done:
188         TALLOC_FREE(posx);
189         TALLOC_FREE(smb_fname_tmp);
190         return status;
191 }
192 #endif
193
194 /********************************************************************
195  Roundup a value to the nearest allocation roundup size boundary.
196  Only do this for Windows clients.
197 ********************************************************************/
198
199 uint64_t smb_roundup(connection_struct *conn, uint64_t val)
200 {
201         uint64_t rval = lp_allocation_roundup_size(SNUM(conn));
202
203         /* Only roundup for Windows clients. */
204         enum remote_arch_types ra_type = get_remote_arch();
205         if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
206                 val = SMB_ROUNDUP(val,rval);
207         }
208         return val;
209 }
210
211 /****************************************************************************
212  Utility functions for dealing with extended attributes.
213 ****************************************************************************/
214
215 /****************************************************************************
216  Refuse to allow clients to overwrite our private xattrs.
217 ****************************************************************************/
218
219 bool samba_private_attr_name(const char *unix_ea_name)
220 {
221         static const char * const prohibited_ea_names[] = {
222                 SAMBA_POSIX_INHERITANCE_EA_NAME,
223                 SAMBA_XATTR_DOS_ATTRIB,
224                 SAMBA_XATTR_MARKER,
225                 XATTR_NTACL_NAME,
226                 NULL
227         };
228
229         int i;
230
231         for (i = 0; prohibited_ea_names[i]; i++) {
232                 if (strequal( prohibited_ea_names[i], unix_ea_name))
233                         return true;
234         }
235         if (strncasecmp_m(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
236                         strlen(SAMBA_XATTR_DOSSTREAM_PREFIX)) == 0) {
237                 return true;
238         }
239         return false;
240 }
241
242 /****************************************************************************
243  Get one EA value. Fill in a struct ea_struct.
244 ****************************************************************************/
245
246 NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx,
247                         connection_struct *conn,
248                         files_struct *fsp,
249                         const struct smb_filename *smb_fname,
250                         const char *ea_name,
251                         struct ea_struct *pea)
252 {
253         /* Get the value of this xattr. Max size is 64k. */
254         size_t attr_size = 256;
255         char *val = NULL;
256         ssize_t sizeret;
257
258  again:
259
260         val = talloc_realloc(mem_ctx, val, char, attr_size);
261         if (!val) {
262                 return NT_STATUS_NO_MEMORY;
263         }
264
265         if (fsp && !fsp->fsp_flags.is_pathref && fsp_get_io_fd(fsp) != -1) {
266                 sizeret = SMB_VFS_FGETXATTR(fsp, ea_name, val, attr_size);
267         } else {
268                 sizeret = SMB_VFS_GETXATTR(conn, smb_fname,
269                                 ea_name, val, attr_size);
270         }
271
272         if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
273                 attr_size = 65536;
274                 goto again;
275         }
276
277         if (sizeret == -1) {
278                 return map_nt_error_from_unix(errno);
279         }
280
281         DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name, (unsigned int)sizeret));
282         dump_data(10, (uint8_t *)val, sizeret);
283
284         pea->flags = 0;
285         if (strnequal(ea_name, "user.", 5)) {
286                 pea->name = talloc_strdup(mem_ctx, &ea_name[5]);
287         } else {
288                 pea->name = talloc_strdup(mem_ctx, ea_name);
289         }
290         if (pea->name == NULL) {
291                 TALLOC_FREE(val);
292                 return NT_STATUS_NO_MEMORY;
293         }
294         pea->value.data = (unsigned char *)val;
295         pea->value.length = (size_t)sizeret;
296         return NT_STATUS_OK;
297 }
298
299 NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
300                                 connection_struct *conn,
301                                 files_struct *fsp,
302                                 const struct smb_filename *smb_fname,
303                                 char ***pnames,
304                                 size_t *pnum_names)
305 {
306         char smallbuf[1024];
307         /* Get a list of all xattrs. Max namesize is 64k. */
308         size_t ea_namelist_size = 1024;
309         char *ea_namelist = smallbuf;
310         char *to_free = NULL;
311
312         char *p;
313         char **names;
314         size_t num_names;
315         ssize_t sizeret = -1;
316         NTSTATUS status;
317
318         if (pnames) {
319                 *pnames = NULL;
320         }
321         *pnum_names = 0;
322
323         status = refuse_symlink(conn, fsp, smb_fname);
324         if (!NT_STATUS_IS_OK(status)) {
325                 /*
326                  * Just return no EA's on a symlink.
327                  */
328                 return NT_STATUS_OK;
329         }
330
331         if (fsp && !fsp->fsp_flags.is_pathref && fsp_get_io_fd(fsp) != -1) {
332                 sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
333                                              ea_namelist_size);
334         } else {
335                 sizeret = SMB_VFS_LISTXATTR(conn,
336                                             smb_fname,
337                                             ea_namelist,
338                                             ea_namelist_size);
339         }
340
341         if ((sizeret == -1) && (errno == ERANGE)) {
342                 ea_namelist_size = 65536;
343                 ea_namelist = talloc_array(mem_ctx, char, ea_namelist_size);
344                 if (ea_namelist == NULL) {
345                         return NT_STATUS_NO_MEMORY;
346                 }
347                 to_free = ea_namelist;
348
349                 if (fsp &&
350                     !fsp->fsp_flags.is_pathref &&
351                     fsp_get_io_fd(fsp) != -1)
352                 {
353                         sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
354                                                      ea_namelist_size);
355                 } else {
356                         sizeret = SMB_VFS_LISTXATTR(conn,
357                                                     smb_fname,
358                                                     ea_namelist,
359                                                     ea_namelist_size);
360                 }
361         }
362
363         if (sizeret == -1) {
364                 status = map_nt_error_from_unix(errno);
365                 TALLOC_FREE(to_free);
366                 return status;
367         }
368
369         DBG_DEBUG("ea_namelist size = %zd\n", sizeret);
370
371         if (sizeret == 0) {
372                 TALLOC_FREE(to_free);
373                 return NT_STATUS_OK;
374         }
375
376         /*
377          * Ensure the result is 0-terminated
378          */
379
380         if (ea_namelist[sizeret-1] != '\0') {
381                 TALLOC_FREE(to_free);
382                 return NT_STATUS_INTERNAL_ERROR;
383         }
384
385         /*
386          * count the names
387          */
388         num_names = 0;
389
390         for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
391                 num_names += 1;
392         }
393
394         *pnum_names = num_names;
395
396         if (pnames == NULL) {
397                 TALLOC_FREE(to_free);
398                 return NT_STATUS_OK;
399         }
400
401         names = talloc_array(mem_ctx, char *, num_names);
402         if (names == NULL) {
403                 DEBUG(0, ("talloc failed\n"));
404                 TALLOC_FREE(to_free);
405                 return NT_STATUS_NO_MEMORY;
406         }
407
408         if (ea_namelist == smallbuf) {
409                 ea_namelist = talloc_memdup(names, smallbuf, sizeret);
410                 if (ea_namelist == NULL) {
411                         TALLOC_FREE(names);
412                         return NT_STATUS_NO_MEMORY;
413                 }
414         } else {
415                 talloc_steal(names, ea_namelist);
416
417                 ea_namelist = talloc_realloc(names, ea_namelist, char,
418                                              sizeret);
419                 if (ea_namelist == NULL) {
420                         TALLOC_FREE(names);
421                         return NT_STATUS_NO_MEMORY;
422                 }
423         }
424
425         num_names = 0;
426
427         for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
428                 names[num_names++] = p;
429         }
430
431         *pnames = names;
432
433         return NT_STATUS_OK;
434 }
435
436 /****************************************************************************
437  Return a linked list of the total EA's. Plus the total size
438 ****************************************************************************/
439
440 static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx,
441                                 connection_struct *conn,
442                                 files_struct *fsp,
443                                 const struct smb_filename *smb_fname,
444                                 size_t *pea_total_len,
445                                 struct ea_list **ea_list)
446 {
447         /* Get a list of all xattrs. Max namesize is 64k. */
448         size_t i, num_names;
449         char **names;
450         struct ea_list *ea_list_head = NULL;
451         bool posix_pathnames = false;
452         NTSTATUS status;
453
454         *pea_total_len = 0;
455         *ea_list = NULL;
456
457         if (!lp_ea_support(SNUM(conn))) {
458                 return NT_STATUS_OK;
459         }
460
461         if (fsp) {
462                 posix_pathnames =
463                         (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
464         } else {
465                 posix_pathnames = (smb_fname->flags & SMB_FILENAME_POSIX_PATH);
466         }
467
468         status = get_ea_names_from_file(talloc_tos(),
469                                 conn,
470                                 fsp,
471                                 smb_fname,
472                                 &names,
473                                 &num_names);
474
475         if (!NT_STATUS_IS_OK(status)) {
476                 return status;
477         }
478
479         if (num_names == 0) {
480                 return NT_STATUS_OK;
481         }
482
483         for (i=0; i<num_names; i++) {
484                 struct ea_list *listp;
485                 fstring dos_ea_name;
486
487                 if (strnequal(names[i], "system.", 7)
488                     || samba_private_attr_name(names[i]))
489                         continue;
490
491                 /*
492                  * Filter out any underlying POSIX EA names
493                  * that a Windows client can't handle.
494                  */
495                 if (!posix_pathnames &&
496                                 is_invalid_windows_ea_name(names[i])) {
497                         continue;
498                 }
499
500                 listp = talloc(mem_ctx, struct ea_list);
501                 if (listp == NULL) {
502                         return NT_STATUS_NO_MEMORY;
503                 }
504
505                 status = get_ea_value(listp,
506                                         conn,
507                                         fsp,
508                                         smb_fname,
509                                         names[i],
510                                         &listp->ea);
511
512                 if (!NT_STATUS_IS_OK(status)) {
513                         TALLOC_FREE(listp);
514                         return status;
515                 }
516
517                 if (listp->ea.value.length == 0) {
518                         /*
519                          * We can never return a zero length EA.
520                          * Windows reports the EA's as corrupted.
521                          */
522                         TALLOC_FREE(listp);
523                         continue;
524                 }
525
526                 push_ascii_fstring(dos_ea_name, listp->ea.name);
527
528                 *pea_total_len +=
529                         4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
530
531                 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
532                           "= %u\n", (unsigned int)*pea_total_len, dos_ea_name,
533                           (unsigned int)listp->ea.value.length));
534
535                 DLIST_ADD_END(ea_list_head, listp);
536
537         }
538
539         /* Add on 4 for total length. */
540         if (*pea_total_len) {
541                 *pea_total_len += 4;
542         }
543
544         DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
545                    (unsigned int)*pea_total_len));
546
547         *ea_list = ea_list_head;
548         return NT_STATUS_OK;
549 }
550
551 static NTSTATUS get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
552                                       const struct smb_filename *smb_fname, size_t *pea_total_len, struct ea_list **ea_list)
553 {
554         *pea_total_len = 0;
555         *ea_list = NULL;
556
557         if (!lp_ea_support(SNUM(conn))) {
558                 return NT_STATUS_OK;
559         }
560
561         if (is_ntfs_stream_smb_fname(smb_fname)) {
562                 return NT_STATUS_INVALID_PARAMETER;
563         }
564
565         return get_ea_list_from_file_path(mem_ctx,
566                                 conn,
567                                 fsp,
568                                 smb_fname,
569                                 pea_total_len,
570                                 ea_list);
571 }
572
573 /****************************************************************************
574  Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
575  that was filled.
576 ****************************************************************************/
577
578 static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
579         connection_struct *conn, struct ea_list *ea_list)
580 {
581         unsigned int ret_data_size = 4;
582         char *p = pdata;
583
584         SMB_ASSERT(total_data_size >= 4);
585
586         if (!lp_ea_support(SNUM(conn))) {
587                 SIVAL(pdata,4,0);
588                 return 4;
589         }
590
591         for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
592                 size_t dos_namelen;
593                 fstring dos_ea_name;
594                 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
595                 dos_namelen = strlen(dos_ea_name);
596                 if (dos_namelen > 255 || dos_namelen == 0) {
597                         break;
598                 }
599                 if (ea_list->ea.value.length > 65535) {
600                         break;
601                 }
602                 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
603                         break;
604                 }
605
606                 /* We know we have room. */
607                 SCVAL(p,0,ea_list->ea.flags);
608                 SCVAL(p,1,dos_namelen);
609                 SSVAL(p,2,ea_list->ea.value.length);
610                 strlcpy(p+4, dos_ea_name, dos_namelen+1);
611                 if (ea_list->ea.value.length > 0) {
612                         memcpy(p + 4 + dos_namelen + 1,
613                                ea_list->ea.value.data,
614                                ea_list->ea.value.length);
615                 }
616
617                 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
618                 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
619         }
620
621         ret_data_size = PTR_DIFF(p, pdata);
622         DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
623         SIVAL(pdata,0,ret_data_size);
624         return ret_data_size;
625 }
626
627 static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
628                                        char *pdata,
629                                        unsigned int total_data_size,
630                                        unsigned int *ret_data_size,
631                                        connection_struct *conn,
632                                        struct ea_list *ea_list)
633 {
634         uint8_t *p = (uint8_t *)pdata;
635         uint8_t *last_start = NULL;
636         bool do_store_data = (pdata != NULL);
637
638         *ret_data_size = 0;
639
640         if (!lp_ea_support(SNUM(conn))) {
641                 return NT_STATUS_NO_EAS_ON_FILE;
642         }
643
644         for (; ea_list; ea_list = ea_list->next) {
645                 size_t dos_namelen;
646                 fstring dos_ea_name;
647                 size_t this_size;
648                 size_t pad = 0;
649
650                 if (last_start != NULL && do_store_data) {
651                         SIVAL(last_start, 0, PTR_DIFF(p, last_start));
652                 }
653                 last_start = p;
654
655                 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
656                 dos_namelen = strlen(dos_ea_name);
657                 if (dos_namelen > 255 || dos_namelen == 0) {
658                         return NT_STATUS_INTERNAL_ERROR;
659                 }
660                 if (ea_list->ea.value.length > 65535) {
661                         return NT_STATUS_INTERNAL_ERROR;
662                 }
663
664                 this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length;
665
666                 if (ea_list->next) {
667                         pad = (4 - (this_size % 4)) % 4;
668                         this_size += pad;
669                 }
670
671                 if (do_store_data) {
672                         if (this_size > total_data_size) {
673                                 return NT_STATUS_INFO_LENGTH_MISMATCH;
674                         }
675
676                         /* We know we have room. */
677                         SIVAL(p, 0x00, 0); /* next offset */
678                         SCVAL(p, 0x04, ea_list->ea.flags);
679                         SCVAL(p, 0x05, dos_namelen);
680                         SSVAL(p, 0x06, ea_list->ea.value.length);
681                         strlcpy((char *)(p+0x08), dos_ea_name, dos_namelen+1);
682                         memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
683                         if (pad) {
684                                 memset(p + 0x08 + dos_namelen + 1 + ea_list->ea.value.length,
685                                         '\0',
686                                         pad);
687                         }
688                         total_data_size -= this_size;
689                 }
690
691                 p += this_size;
692         }
693
694         *ret_data_size = PTR_DIFF(p, pdata);
695         DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size));
696         return NT_STATUS_OK;
697 }
698
699 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const struct smb_filename *smb_fname)
700 {
701         size_t total_ea_len = 0;
702         TALLOC_CTX *mem_ctx;
703         struct ea_list *ea_list = NULL;
704
705         if (!lp_ea_support(SNUM(conn))) {
706                 return 0;
707         }
708         mem_ctx = talloc_stackframe();
709
710         /* If this is a stream fsp, then we need to instead find the
711          * estimated ea len from the main file, not the stream
712          * (streams cannot have EAs), but the estimate isn't just 0 in
713          * this case! */
714         if (is_ntfs_stream_smb_fname(smb_fname)) {
715                 fsp = NULL;
716         }
717         (void)get_ea_list_from_file_path(mem_ctx,
718                                 conn,
719                                 fsp,
720                                 smb_fname,
721                                 &total_ea_len,
722                                 &ea_list);
723         if(conn->sconn->using_smb2) {
724                 NTSTATUS status;
725                 unsigned int ret_data_size;
726                 /*
727                  * We're going to be using fill_ea_chained_buffer() to
728                  * marshall EA's - this size is significantly larger
729                  * than the SMB1 buffer. Re-calculate the size without
730                  * marshalling.
731                  */
732                 status = fill_ea_chained_buffer(mem_ctx,
733                                                 NULL,
734                                                 0,
735                                                 &ret_data_size,
736                                                 conn,
737                                                 ea_list);
738                 if (!NT_STATUS_IS_OK(status)) {
739                         ret_data_size = 0;
740                 }
741                 total_ea_len = ret_data_size;
742         }
743         TALLOC_FREE(mem_ctx);
744         return total_ea_len;
745 }
746
747 /****************************************************************************
748  Ensure the EA name is case insensitive by matching any existing EA name.
749 ****************************************************************************/
750
751 static void canonicalize_ea_name(connection_struct *conn,
752                         files_struct *fsp,
753                         const struct smb_filename *smb_fname,
754                         fstring unix_ea_name)
755 {
756         size_t total_ea_len;
757         TALLOC_CTX *mem_ctx = talloc_tos();
758         struct ea_list *ea_list;
759         NTSTATUS status = get_ea_list_from_file_path(mem_ctx,
760                                         conn,
761                                         fsp,
762                                         smb_fname,
763                                         &total_ea_len,
764                                         &ea_list);
765         if (!NT_STATUS_IS_OK(status)) {
766                 return;
767         }
768
769         for (; ea_list; ea_list = ea_list->next) {
770                 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
771                         DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
772                                 &unix_ea_name[5], ea_list->ea.name));
773                         strlcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-5);
774                         break;
775                 }
776         }
777 }
778
779 /****************************************************************************
780  Set or delete an extended attribute.
781 ****************************************************************************/
782
783 NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
784                 const struct smb_filename *smb_fname, struct ea_list *ea_list)
785 {
786         NTSTATUS status;
787         bool posix_pathnames = false;
788
789         if (!lp_ea_support(SNUM(conn))) {
790                 return NT_STATUS_EAS_NOT_SUPPORTED;
791         }
792
793         if (fsp) {
794                 posix_pathnames =
795                         (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
796         } else {
797                 posix_pathnames = (smb_fname->flags & SMB_FILENAME_POSIX_PATH);
798         }
799
800         status = refuse_symlink(conn, fsp, smb_fname);
801         if (!NT_STATUS_IS_OK(status)) {
802                 return status;
803         }
804
805         if (fsp != NULL) {
806                 status = check_access_fsp(fsp, FILE_WRITE_EA);
807         } else {
808                 status = smbd_check_access_rights(conn,
809                                 conn->cwd_fsp,
810                                 smb_fname,
811                                 false,
812                                 FILE_WRITE_EA);
813         }
814         if (!NT_STATUS_IS_OK(status)) {
815                 return status;
816         }
817
818         /* Setting EAs on streams isn't supported. */
819         if (is_ntfs_stream_smb_fname(smb_fname)) {
820                 return NT_STATUS_INVALID_PARAMETER;
821         }
822
823         /*
824          * Filter out invalid Windows EA names - before
825          * we set *any* of them.
826          */
827
828         if (!posix_pathnames && ea_list_has_invalid_name(ea_list)) {
829                 return STATUS_INVALID_EA_NAME;
830         }
831
832         for (;ea_list; ea_list = ea_list->next) {
833                 int ret;
834                 fstring unix_ea_name;
835
836                 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
837                 fstrcat(unix_ea_name, ea_list->ea.name);
838
839                 canonicalize_ea_name(conn,
840                                 fsp,
841                                 smb_fname,
842                                 unix_ea_name);
843
844                 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
845
846                 if (samba_private_attr_name(unix_ea_name)) {
847                         DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
848                         return NT_STATUS_ACCESS_DENIED;
849                 }
850
851                 if (ea_list->ea.value.length == 0) {
852                         /* Remove the attribute. */
853                         if (fsp &&
854                             !fsp->fsp_flags.is_pathref &&
855                             fsp_get_io_fd(fsp) != -1)
856                         {
857                                 DEBUG(10,("set_ea: deleting ea name %s on "
858                                           "file %s by file descriptor.\n",
859                                           unix_ea_name, fsp_str_dbg(fsp)));
860                                 ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
861                         } else {
862                                 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
863                                         unix_ea_name, smb_fname->base_name));
864                                 ret = SMB_VFS_REMOVEXATTR(conn,
865                                                 smb_fname,
866                                                 unix_ea_name);
867                         }
868 #ifdef ENOATTR
869                         /* Removing a non existent attribute always succeeds. */
870                         if (ret == -1 && errno == ENOATTR) {
871                                 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
872                                                 unix_ea_name));
873                                 ret = 0;
874                         }
875 #endif
876                 } else {
877                         if (fsp &&
878                             !fsp->fsp_flags.is_pathref &&
879                             fsp_get_io_fd(fsp) != -1)
880                         {
881                                 DEBUG(10,("set_ea: setting ea name %s on file "
882                                           "%s by file descriptor.\n",
883                                           unix_ea_name, fsp_str_dbg(fsp)));
884                                 ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
885                                                         ea_list->ea.value.data, ea_list->ea.value.length, 0);
886                         } else {
887                                 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
888                                         unix_ea_name, smb_fname->base_name));
889                                 ret = SMB_VFS_SETXATTR(conn,
890                                                 smb_fname,
891                                                 unix_ea_name,
892                                                 ea_list->ea.value.data,
893                                                 ea_list->ea.value.length,
894                                                 0);
895                         }
896                 }
897
898                 if (ret == -1) {
899 #ifdef ENOTSUP
900                         if (errno == ENOTSUP) {
901                                 return NT_STATUS_EAS_NOT_SUPPORTED;
902                         }
903 #endif
904                         return map_nt_error_from_unix(errno);
905                 }
906
907         }
908         return NT_STATUS_OK;
909 }
910 /****************************************************************************
911  Read a list of EA names from an incoming data buffer. Create an ea_list with them.
912 ****************************************************************************/
913
914 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
915 {
916         struct ea_list *ea_list_head = NULL;
917         size_t converted_size, offset = 0;
918
919         while (offset + 2 < data_size) {
920                 struct ea_list *eal = talloc_zero(ctx, struct ea_list);
921                 unsigned int namelen = CVAL(pdata,offset);
922
923                 offset++; /* Go past the namelen byte. */
924
925                 /* integer wrap paranioa. */
926                 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
927                                 (offset > data_size) || (namelen > data_size) ||
928                                 (offset + namelen >= data_size)) {
929                         break;
930                 }
931                 /* Ensure the name is null terminated. */
932                 if (pdata[offset + namelen] != '\0') {
933                         return NULL;
934                 }
935                 if (!pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset],
936                                        &converted_size)) {
937                         DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
938                                  "failed: %s", strerror(errno)));
939                 }
940                 if (!eal->ea.name) {
941                         return NULL;
942                 }
943
944                 offset += (namelen + 1); /* Go past the name + terminating zero. */
945                 DLIST_ADD_END(ea_list_head, eal);
946                 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
947         }
948
949         return ea_list_head;
950 }
951
952 /****************************************************************************
953  Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
954 ****************************************************************************/
955
956 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
957 {
958         struct ea_list *ea_list_head = NULL;
959         size_t offset = 0;
960         size_t bytes_used = 0;
961
962         while (offset < data_size) {
963                 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
964
965                 if (!eal) {
966                         return NULL;
967                 }
968
969                 DLIST_ADD_END(ea_list_head, eal);
970                 offset += bytes_used;
971         }
972
973         return ea_list_head;
974 }
975
976 /****************************************************************************
977  Count the total EA size needed.
978 ****************************************************************************/
979
980 static size_t ea_list_size(struct ea_list *ealist)
981 {
982         fstring dos_ea_name;
983         struct ea_list *listp;
984         size_t ret = 0;
985
986         for (listp = ealist; listp; listp = listp->next) {
987                 push_ascii_fstring(dos_ea_name, listp->ea.name);
988                 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
989         }
990         /* Add on 4 for total length. */
991         if (ret) {
992                 ret += 4;
993         }
994
995         return ret;
996 }
997
998 /****************************************************************************
999  Return a union of EA's from a file list and a list of names.
1000  The TALLOC context for the two lists *MUST* be identical as we steal
1001  memory from one list to add to another. JRA.
1002 ****************************************************************************/
1003
1004 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
1005 {
1006         struct ea_list *nlistp, *flistp;
1007
1008         for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
1009                 for (flistp = file_list; flistp; flistp = flistp->next) {
1010                         if (strequal(nlistp->ea.name, flistp->ea.name)) {
1011                                 break;
1012                         }
1013                 }
1014
1015                 if (flistp) {
1016                         /* Copy the data from this entry. */
1017                         nlistp->ea.flags = flistp->ea.flags;
1018                         nlistp->ea.value = flistp->ea.value;
1019                 } else {
1020                         /* Null entry. */
1021                         nlistp->ea.flags = 0;
1022                         ZERO_STRUCT(nlistp->ea.value);
1023                 }
1024         }
1025
1026         *total_ea_len = ea_list_size(name_list);
1027         return name_list;
1028 }
1029
1030 /****************************************************************************
1031   Send the required number of replies back.
1032   We assume all fields other than the data fields are
1033   set correctly for the type of call.
1034   HACK ! Always assumes smb_setup field is zero.
1035 ****************************************************************************/
1036
1037 void send_trans2_replies(connection_struct *conn,
1038                         struct smb_request *req,
1039                         NTSTATUS status,
1040                          const char *params,
1041                          int paramsize,
1042                          const char *pdata,
1043                          int datasize,
1044                          int max_data_bytes)
1045 {
1046         /* As we are using a protocol > LANMAN1 then the max_send
1047          variable must have been set in the sessetupX call.
1048          This takes precedence over the max_xmit field in the
1049          global struct. These different max_xmit variables should
1050          be merged as this is now too confusing */
1051
1052         int data_to_send = datasize;
1053         int params_to_send = paramsize;
1054         int useable_space;
1055         const char *pp = params;
1056         const char *pd = pdata;
1057         int params_sent_thistime, data_sent_thistime, total_sent_thistime;
1058         int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
1059         int data_alignment_offset = 0;
1060         bool overflow = False;
1061         struct smbXsrv_connection *xconn = req->xconn;
1062         int max_send = xconn->smb1.sessions.max_send;
1063
1064         /* Modify the data_to_send and datasize and set the error if
1065            we're trying to send more than max_data_bytes. We still send
1066            the part of the packet(s) that fit. Strange, but needed
1067            for OS/2. */
1068
1069         if (max_data_bytes > 0 && datasize > max_data_bytes) {
1070                 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
1071                         max_data_bytes, datasize ));
1072                 datasize = data_to_send = max_data_bytes;
1073                 overflow = True;
1074         }
1075
1076         /* If there genuinely are no parameters or data to send just send the empty packet */
1077
1078         if(params_to_send == 0 && data_to_send == 0) {
1079                 reply_outbuf(req, 10, 0);
1080                 if (NT_STATUS_V(status)) {
1081                         uint8_t eclass;
1082                         uint32_t ecode;
1083                         ntstatus_to_dos(status, &eclass, &ecode);
1084                         error_packet_set((char *)req->outbuf,
1085                                         eclass, ecode, status,
1086                                         __LINE__,__FILE__);
1087                 }
1088                 show_msg((char *)req->outbuf);
1089                 if (!srv_send_smb(xconn,
1090                                 (char *)req->outbuf,
1091                                 true, req->seqnum+1,
1092                                 IS_CONN_ENCRYPTED(conn),
1093                                 &req->pcd)) {
1094                         exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
1095                 }
1096                 TALLOC_FREE(req->outbuf);
1097                 return;
1098         }
1099
1100         /* When sending params and data ensure that both are nicely aligned */
1101         /* Only do this alignment when there is also data to send - else
1102                 can cause NT redirector problems. */
1103
1104         if (((params_to_send % 4) != 0) && (data_to_send != 0))
1105                 data_alignment_offset = 4 - (params_to_send % 4);
1106
1107         /* Space is bufsize minus Netbios over TCP header minus SMB header */
1108         /* The alignment_offset is to align the param bytes on an even byte
1109                 boundary. NT 4.0 Beta needs this to work correctly. */
1110
1111         useable_space = max_send - (smb_size
1112                                     + 2 * 10 /* wct */
1113                                     + alignment_offset
1114                                     + data_alignment_offset);
1115
1116         if (useable_space < 0) {
1117                 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
1118                           "= %d!!!", useable_space));
1119                 exit_server_cleanly("send_trans2_replies: Not enough space");
1120         }
1121
1122         while (params_to_send || data_to_send) {
1123                 /* Calculate whether we will totally or partially fill this packet */
1124
1125                 total_sent_thistime = params_to_send + data_to_send;
1126
1127                 /* We can never send more than useable_space */
1128                 /*
1129                  * Note that 'useable_space' does not include the alignment offsets,
1130                  * but we must include the alignment offsets in the calculation of
1131                  * the length of the data we send over the wire, as the alignment offsets
1132                  * are sent here. Fix from Marc_Jacobsen@hp.com.
1133                  */
1134
1135                 total_sent_thistime = MIN(total_sent_thistime, useable_space);
1136
1137                 reply_outbuf(req, 10, total_sent_thistime + alignment_offset
1138                              + data_alignment_offset);
1139
1140                 /* Set total params and data to be sent */
1141                 SSVAL(req->outbuf,smb_tprcnt,paramsize);
1142                 SSVAL(req->outbuf,smb_tdrcnt,datasize);
1143
1144                 /* Calculate how many parameters and data we can fit into
1145                  * this packet. Parameters get precedence
1146                  */
1147
1148                 params_sent_thistime = MIN(params_to_send,useable_space);
1149                 data_sent_thistime = useable_space - params_sent_thistime;
1150                 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
1151
1152                 SSVAL(req->outbuf,smb_prcnt, params_sent_thistime);
1153
1154                 /* smb_proff is the offset from the start of the SMB header to the
1155                         parameter bytes, however the first 4 bytes of outbuf are
1156                         the Netbios over TCP header. Thus use smb_base() to subtract
1157                         them from the calculation */
1158
1159                 SSVAL(req->outbuf,smb_proff,
1160                       ((smb_buf(req->outbuf)+alignment_offset)
1161                        - smb_base(req->outbuf)));
1162
1163                 if(params_sent_thistime == 0)
1164                         SSVAL(req->outbuf,smb_prdisp,0);
1165                 else
1166                         /* Absolute displacement of param bytes sent in this packet */
1167                         SSVAL(req->outbuf,smb_prdisp,pp - params);
1168
1169                 SSVAL(req->outbuf,smb_drcnt, data_sent_thistime);
1170                 if(data_sent_thistime == 0) {
1171                         SSVAL(req->outbuf,smb_droff,0);
1172                         SSVAL(req->outbuf,smb_drdisp, 0);
1173                 } else {
1174                         /* The offset of the data bytes is the offset of the
1175                                 parameter bytes plus the number of parameters being sent this time */
1176                         SSVAL(req->outbuf, smb_droff,
1177                               ((smb_buf(req->outbuf)+alignment_offset)
1178                                - smb_base(req->outbuf))
1179                               + params_sent_thistime + data_alignment_offset);
1180                         SSVAL(req->outbuf,smb_drdisp, pd - pdata);
1181                 }
1182
1183                 /* Initialize the padding for alignment */
1184
1185                 if (alignment_offset != 0) {
1186                         memset(smb_buf(req->outbuf), 0, alignment_offset);
1187                 }
1188
1189                 /* Copy the param bytes into the packet */
1190
1191                 if(params_sent_thistime) {
1192                         memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
1193                                params_sent_thistime);
1194                 }
1195
1196                 /* Copy in the data bytes */
1197                 if(data_sent_thistime) {
1198                         if (data_alignment_offset != 0) {
1199                                 memset((smb_buf(req->outbuf)+alignment_offset+
1200                                         params_sent_thistime), 0,
1201                                        data_alignment_offset);
1202                         }
1203                         memcpy(smb_buf(req->outbuf)+alignment_offset
1204                                +params_sent_thistime+data_alignment_offset,
1205                                pd,data_sent_thistime);
1206                 }
1207
1208                 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
1209                         params_sent_thistime, data_sent_thistime, useable_space));
1210                 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
1211                         params_to_send, data_to_send, paramsize, datasize));
1212
1213                 if (overflow) {
1214                         error_packet_set((char *)req->outbuf,
1215                                          ERRDOS,ERRbufferoverflow,
1216                                          STATUS_BUFFER_OVERFLOW,
1217                                          __LINE__,__FILE__);
1218                 } else if (NT_STATUS_V(status)) {
1219                         uint8_t eclass;
1220                         uint32_t ecode;
1221                         ntstatus_to_dos(status, &eclass, &ecode);
1222                         error_packet_set((char *)req->outbuf,
1223                                         eclass, ecode, status,
1224                                         __LINE__,__FILE__);
1225                 }
1226
1227                 /* Send the packet */
1228                 show_msg((char *)req->outbuf);
1229                 if (!srv_send_smb(xconn,
1230                                 (char *)req->outbuf,
1231                                 true, req->seqnum+1,
1232                                 IS_CONN_ENCRYPTED(conn),
1233                                 &req->pcd))
1234                         exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
1235
1236                 TALLOC_FREE(req->outbuf);
1237
1238                 pp += params_sent_thistime;
1239                 pd += data_sent_thistime;
1240
1241                 params_to_send -= params_sent_thistime;
1242                 data_to_send -= data_sent_thistime;
1243
1244                 /* Sanity check */
1245                 if(params_to_send < 0 || data_to_send < 0) {
1246                         DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
1247                                 params_to_send, data_to_send));
1248                         return;
1249                 }
1250         }
1251
1252         return;
1253 }
1254
1255 /****************************************************************************
1256  Reply to a TRANSACT2_OPEN.
1257 ****************************************************************************/
1258
1259 static void call_trans2open(connection_struct *conn,
1260                             struct smb_request *req,
1261                             char **pparams, int total_params,
1262                             char **ppdata, int total_data,
1263                             unsigned int max_data_bytes)
1264 {
1265         struct smb_filename *smb_fname = NULL;
1266         char *params = *pparams;
1267         char *pdata = *ppdata;
1268         int deny_mode;
1269         int32_t open_attr;
1270         bool oplock_request;
1271 #if 0
1272         bool return_additional_info;
1273         int16 open_sattr;
1274         time_t open_time;
1275 #endif
1276         int open_ofun;
1277         uint32_t open_size;
1278         char *pname;
1279         char *fname = NULL;
1280         off_t size=0;
1281         int fattr=0,mtime=0;
1282         SMB_INO_T inode = 0;
1283         int smb_action = 0;
1284         files_struct *fsp;
1285         struct ea_list *ea_list = NULL;
1286         uint16_t flags = 0;
1287         NTSTATUS status;
1288         uint32_t access_mask;
1289         uint32_t share_mode;
1290         uint32_t create_disposition;
1291         uint32_t create_options = 0;
1292         uint32_t private_flags = 0;
1293         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
1294         TALLOC_CTX *ctx = talloc_tos();
1295
1296         /*
1297          * Ensure we have enough parameters to perform the operation.
1298          */
1299
1300         if (total_params < 29) {
1301                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1302                 goto out;
1303         }
1304
1305         flags = SVAL(params, 0);
1306         deny_mode = SVAL(params, 2);
1307         open_attr = SVAL(params,6);
1308         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
1309         if (oplock_request) {
1310                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
1311         }
1312
1313 #if 0
1314         return_additional_info = BITSETW(params,0);
1315         open_sattr = SVAL(params, 4);
1316         open_time = make_unix_date3(params+8);
1317 #endif
1318         open_ofun = SVAL(params,12);
1319         open_size = IVAL(params,14);
1320         pname = &params[28];
1321
1322         if (IS_IPC(conn)) {
1323                 reply_nterror(req, NT_STATUS_NETWORK_ACCESS_DENIED);
1324                 goto out;
1325         }
1326
1327         if (req->posix_pathnames) {
1328                 srvstr_get_path_posix(ctx,
1329                         params,
1330                         req->flags2,
1331                         &fname,
1332                         pname,
1333                         total_params - 28,
1334                         STR_TERMINATE,
1335                         &status);
1336         } else {
1337                 srvstr_get_path(ctx,
1338                         params,
1339                         req->flags2,
1340                         &fname,
1341                         pname,
1342                         total_params - 28,
1343                         STR_TERMINATE,
1344                         &status);
1345         }
1346         if (!NT_STATUS_IS_OK(status)) {
1347                 reply_nterror(req, status);
1348                 goto out;
1349         }
1350
1351         DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
1352                 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
1353                 (unsigned int)open_ofun, open_size));
1354
1355         status = filename_convert(ctx,
1356                                 conn,
1357                                 fname,
1358                                 ucf_flags,
1359                                 0,
1360                                 &smb_fname);
1361         if (!NT_STATUS_IS_OK(status)) {
1362                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1363                         reply_botherror(req,
1364                                 NT_STATUS_PATH_NOT_COVERED,
1365                                 ERRSRV, ERRbadpath);
1366                         goto out;
1367                 }
1368                 reply_nterror(req, status);
1369                 goto out;
1370         }
1371
1372         if (open_ofun == 0) {
1373                 reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
1374                 goto out;
1375         }
1376
1377         if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
1378                                          open_ofun,
1379                                          &access_mask, &share_mode,
1380                                          &create_disposition,
1381                                          &create_options,
1382                                          &private_flags)) {
1383                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1384                 goto out;
1385         }
1386
1387         /* Any data in this call is an EA list. */
1388         if (total_data && (total_data != 4)) {
1389                 if (total_data < 10) {
1390                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1391                         goto out;
1392                 }
1393
1394                 if (IVAL(pdata,0) > total_data) {
1395                         DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
1396                                 IVAL(pdata,0), (unsigned int)total_data));
1397                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1398                         goto out;
1399                 }
1400
1401                 ea_list = read_ea_list(talloc_tos(), pdata + 4,
1402                                        total_data - 4);
1403                 if (!ea_list) {
1404                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1405                         goto out;
1406                 }
1407
1408                 if (!lp_ea_support(SNUM(conn))) {
1409                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1410                         goto out;
1411                 }
1412
1413                 if (!req->posix_pathnames &&
1414                                 ea_list_has_invalid_name(ea_list)) {
1415                         int param_len = 30;
1416                         *pparams = (char *)SMB_REALLOC(*pparams, param_len);
1417                         if(*pparams == NULL ) {
1418                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
1419                                 goto out;
1420                         }
1421                         params = *pparams;
1422                         memset(params, '\0', param_len);
1423                         send_trans2_replies(conn, req, STATUS_INVALID_EA_NAME,
1424                                 params, param_len, NULL, 0, max_data_bytes);
1425                         goto out;
1426                 }
1427         }
1428
1429         status = SMB_VFS_CREATE_FILE(
1430                 conn,                                   /* conn */
1431                 req,                                    /* req */
1432                 smb_fname,                              /* fname */
1433                 access_mask,                            /* access_mask */
1434                 share_mode,                             /* share_access */
1435                 create_disposition,                     /* create_disposition*/
1436                 create_options,                         /* create_options */
1437                 open_attr,                              /* file_attributes */
1438                 oplock_request,                         /* oplock_request */
1439                 NULL,                                   /* lease */
1440                 open_size,                              /* allocation_size */
1441                 private_flags,
1442                 NULL,                                   /* sd */
1443                 ea_list,                                /* ea_list */
1444                 &fsp,                                   /* result */
1445                 &smb_action,                            /* psbuf */
1446                 NULL, NULL);                            /* create context */
1447
1448         if (!NT_STATUS_IS_OK(status)) {
1449                 if (open_was_deferred(req->xconn, req->mid)) {
1450                         /* We have re-scheduled this call. */
1451                         goto out;
1452                 }
1453
1454                 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
1455                         reply_openerror(req, status);
1456                         goto out;
1457                 }
1458
1459                 fsp = fcb_or_dos_open(
1460                         req,
1461                         smb_fname,
1462                         access_mask,
1463                         create_options,
1464                         private_flags);
1465                 if (fsp == NULL) {
1466                         bool ok = defer_smb1_sharing_violation(req);
1467                         if (ok) {
1468                                 goto out;
1469                         }
1470                         reply_openerror(req, status);
1471                         goto out;
1472                 }
1473
1474                 smb_action = FILE_WAS_OPENED;
1475         }
1476
1477         size = get_file_size_stat(&smb_fname->st);
1478         fattr = dos_mode(conn, smb_fname);
1479         mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1480         inode = smb_fname->st.st_ex_ino;
1481         if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
1482                 close_file(req, fsp, ERROR_CLOSE);
1483                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1484                 goto out;
1485         }
1486
1487         /* Realloc the size of parameters and data we will return */
1488         *pparams = (char *)SMB_REALLOC(*pparams, 30);
1489         if(*pparams == NULL ) {
1490                 reply_nterror(req, NT_STATUS_NO_MEMORY);
1491                 goto out;
1492         }
1493         params = *pparams;
1494
1495         SSVAL(params,0,fsp->fnum);
1496         SSVAL(params,2,fattr);
1497         srv_put_dos_date2(params,4, mtime);
1498         SIVAL(params,8, (uint32_t)size);
1499         SSVAL(params,12,deny_mode);
1500         SSVAL(params,14,0); /* open_type - file or directory. */
1501         SSVAL(params,16,0); /* open_state - only valid for IPC device. */
1502
1503         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1504                 smb_action |= EXTENDED_OPLOCK_GRANTED;
1505         }
1506
1507         SSVAL(params,18,smb_action);
1508
1509         /*
1510          * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1511          */
1512         SIVAL(params,20,inode);
1513         SSVAL(params,24,0); /* Padding. */
1514         if (flags & 8) {
1515                 uint32_t ea_size = estimate_ea_size(conn, fsp,
1516                                                   smb_fname);
1517                 SIVAL(params, 26, ea_size);
1518         } else {
1519                 SIVAL(params, 26, 0);
1520         }
1521
1522         /* Send the required number of replies */
1523         send_trans2_replies(conn, req, NT_STATUS_OK, params, 30, *ppdata, 0, max_data_bytes);
1524  out:
1525         TALLOC_FREE(smb_fname);
1526 }
1527
1528 /*********************************************************
1529  Routine to check if a given string matches exactly.
1530  as a special case a mask of "." does NOT match. That
1531  is required for correct wildcard semantics
1532  Case can be significant or not.
1533 **********************************************************/
1534
1535 static bool exact_match(bool has_wild,
1536                         bool case_sensitive,
1537                         const char *str,
1538                         const char *mask)
1539 {
1540         if (mask[0] == '.' && mask[1] == 0) {
1541                 return false;
1542         }
1543
1544         if (has_wild) {
1545                 return false;
1546         }
1547
1548         if (case_sensitive) {
1549                 return strcmp(str,mask)==0;
1550         } else {
1551                 return strcasecmp_m(str,mask) == 0;
1552         }
1553 }
1554
1555 /****************************************************************************
1556  Return the filetype for UNIX extensions.
1557 ****************************************************************************/
1558
1559 static uint32_t unix_filetype(mode_t mode)
1560 {
1561         if(S_ISREG(mode))
1562                 return UNIX_TYPE_FILE;
1563         else if(S_ISDIR(mode))
1564                 return UNIX_TYPE_DIR;
1565 #ifdef S_ISLNK
1566         else if(S_ISLNK(mode))
1567                 return UNIX_TYPE_SYMLINK;
1568 #endif
1569 #ifdef S_ISCHR
1570         else if(S_ISCHR(mode))
1571                 return UNIX_TYPE_CHARDEV;
1572 #endif
1573 #ifdef S_ISBLK
1574         else if(S_ISBLK(mode))
1575                 return UNIX_TYPE_BLKDEV;
1576 #endif
1577 #ifdef S_ISFIFO
1578         else if(S_ISFIFO(mode))
1579                 return UNIX_TYPE_FIFO;
1580 #endif
1581 #ifdef S_ISSOCK
1582         else if(S_ISSOCK(mode))
1583                 return UNIX_TYPE_SOCKET;
1584 #endif
1585
1586         DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
1587         return UNIX_TYPE_UNKNOWN;
1588 }
1589
1590 /****************************************************************************
1591  Map wire perms onto standard UNIX permissions. Obey share restrictions.
1592 ****************************************************************************/
1593
1594 NTSTATUS unix_perms_from_wire(connection_struct *conn,
1595                               const SMB_STRUCT_STAT *psbuf,
1596                               uint32_t perms,
1597                               enum perm_type ptype,
1598                               mode_t *ret_perms)
1599 {
1600         mode_t ret = 0;
1601
1602         if (perms == SMB_MODE_NO_CHANGE) {
1603                 if (!VALID_STAT(*psbuf)) {
1604                         return NT_STATUS_INVALID_PARAMETER;
1605                 } else {
1606                         *ret_perms = psbuf->st_ex_mode;
1607                         return NT_STATUS_OK;
1608                 }
1609         }
1610
1611         ret = wire_perms_to_unix(perms);
1612
1613         if (ptype == PERM_NEW_FILE) {
1614                 /*
1615                  * "create mask"/"force create mode" are
1616                  * only applied to new files, not existing ones.
1617                  */
1618                 ret &= lp_create_mask(SNUM(conn));
1619                 /* Add in force bits */
1620                 ret |= lp_force_create_mode(SNUM(conn));
1621         } else if (ptype == PERM_NEW_DIR) {
1622                 /*
1623                  * "directory mask"/"force directory mode" are
1624                  * only applied to new directories, not existing ones.
1625                  */
1626                 ret &= lp_directory_mask(SNUM(conn));
1627                 /* Add in force bits */
1628                 ret |= lp_force_directory_mode(SNUM(conn));
1629         }
1630
1631         *ret_perms = ret;
1632         return NT_STATUS_OK;
1633 }
1634
1635 /****************************************************************************
1636  Needed to show the msdfs symlinks as directories. Modifies psbuf
1637  to be a directory if it's a msdfs link.
1638 ****************************************************************************/
1639
1640 static bool check_msdfs_link(connection_struct *conn,
1641                                 struct smb_filename *smb_fname)
1642 {
1643         int saved_errno = errno;
1644         if(lp_host_msdfs() &&
1645                 lp_msdfs_root(SNUM(conn)) &&
1646                 is_msdfs_link(conn, smb_fname)) {
1647
1648                 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1649                         "as a directory\n",
1650                         smb_fname->base_name));
1651                 smb_fname->st.st_ex_mode =
1652                         (smb_fname->st.st_ex_mode & 0xFFF) | S_IFDIR;
1653                 errno = saved_errno;
1654                 return true;
1655         }
1656         errno = saved_errno;
1657         return false;
1658 }
1659
1660
1661 /****************************************************************************
1662  Get a level dependent lanman2 dir entry.
1663 ****************************************************************************/
1664
1665 struct smbd_dirptr_lanman2_state {
1666         connection_struct *conn;
1667         uint32_t info_level;
1668         bool check_mangled_names;
1669         bool has_wild;
1670         bool got_exact_match;
1671 };
1672
1673 static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX *ctx,
1674                                          void *private_data,
1675                                          const char *dname,
1676                                          const char *mask,
1677                                          char **_fname)
1678 {
1679         struct smbd_dirptr_lanman2_state *state =
1680                 (struct smbd_dirptr_lanman2_state *)private_data;
1681         bool ok;
1682         char mangled_name[13]; /* mangled 8.3 name. */
1683         bool got_match;
1684         const char *fname;
1685
1686         /* Mangle fname if it's an illegal name. */
1687         if (mangle_must_mangle(dname, state->conn->params)) {
1688                 /*
1689                  * Slow path - ensure we can push the original name as UCS2. If
1690                  * not, then just don't return this name.
1691                  */
1692                 NTSTATUS status;
1693                 size_t ret_len = 0;
1694                 size_t len = (strlen(dname) + 2) * 4; /* Allow enough space. */
1695                 uint8_t *tmp = talloc_array(talloc_tos(),
1696                                         uint8_t,
1697                                         len);
1698
1699                 status = srvstr_push(NULL,
1700                         FLAGS2_UNICODE_STRINGS,
1701                         tmp,
1702                         dname,
1703                         len,
1704                         STR_TERMINATE,
1705                         &ret_len);
1706
1707                 TALLOC_FREE(tmp);
1708
1709                 if (!NT_STATUS_IS_OK(status)) {
1710                         return false;
1711                 }
1712
1713                 ok = name_to_8_3(dname, mangled_name,
1714                                  true, state->conn->params);
1715                 if (!ok) {
1716                         return false;
1717                 }
1718                 fname = mangled_name;
1719         } else {
1720                 fname = dname;
1721         }
1722
1723         got_match = exact_match(state->has_wild,
1724                                 state->conn->case_sensitive,
1725                                 fname, mask);
1726         state->got_exact_match = got_match;
1727         if (!got_match) {
1728                 got_match = mask_match(fname, mask,
1729                                        state->conn->case_sensitive);
1730         }
1731
1732         if(!got_match && state->check_mangled_names &&
1733            !mangle_is_8_3(fname, false, state->conn->params)) {
1734                 /*
1735                  * It turns out that NT matches wildcards against
1736                  * both long *and* short names. This may explain some
1737                  * of the wildcard wierdness from old DOS clients
1738                  * that some people have been seeing.... JRA.
1739                  */
1740                 /* Force the mangling into 8.3. */
1741                 ok = name_to_8_3(fname, mangled_name,
1742                                  false, state->conn->params);
1743                 if (!ok) {
1744                         return false;
1745                 }
1746
1747                 got_match = exact_match(state->has_wild,
1748                                         state->conn->case_sensitive,
1749                                         mangled_name, mask);
1750                 state->got_exact_match = got_match;
1751                 if (!got_match) {
1752                         got_match = mask_match(mangled_name, mask,
1753                                                state->conn->case_sensitive);
1754                 }
1755         }
1756
1757         if (!got_match) {
1758                 return false;
1759         }
1760
1761         *_fname = talloc_strdup(ctx, fname);
1762         if (*_fname == NULL) {
1763                 return false;
1764         }
1765
1766         return true;
1767 }
1768
1769 static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX *ctx,
1770                                         void *private_data,
1771                                         struct smb_filename *smb_fname,
1772                                         bool get_dosmode,
1773                                         uint32_t *_mode)
1774 {
1775         struct smbd_dirptr_lanman2_state *state =
1776                 (struct smbd_dirptr_lanman2_state *)private_data;
1777         bool ms_dfs_link = false;
1778         uint32_t mode = 0;
1779
1780         if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
1781                 if (SMB_VFS_LSTAT(state->conn, smb_fname) != 0) {
1782                         DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1783                                  "Couldn't lstat [%s] (%s)\n",
1784                                  smb_fname_str_dbg(smb_fname),
1785                                  strerror(errno)));
1786                         return false;
1787                 }
1788         } else if (!VALID_STAT(smb_fname->st) &&
1789                    SMB_VFS_STAT(state->conn, smb_fname) != 0) {
1790                 /* Needed to show the msdfs symlinks as
1791                  * directories */
1792
1793                 ms_dfs_link = check_msdfs_link(state->conn,
1794                                                smb_fname);
1795                 if (!ms_dfs_link) {
1796                         DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1797                                  "Couldn't stat [%s] (%s)\n",
1798                                  smb_fname_str_dbg(smb_fname),
1799                                  strerror(errno)));
1800                         return false;
1801                 }
1802         }
1803
1804         if (ms_dfs_link) {
1805                 mode = dos_mode_msdfs(state->conn, smb_fname);
1806         } else if (get_dosmode) {
1807                 mode = dos_mode(state->conn, smb_fname);
1808         }
1809
1810         *_mode = mode;
1811         return true;
1812 }
1813
1814 static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
1815                                     connection_struct *conn,
1816                                     uint16_t flags2,
1817                                     uint32_t info_level,
1818                                     struct ea_list *name_list,
1819                                     bool check_mangled_names,
1820                                     bool requires_resume_key,
1821                                     uint32_t mode,
1822                                     const char *fname,
1823                                     const struct smb_filename *smb_fname,
1824                                     int space_remaining,
1825                                     uint8_t align,
1826                                     bool do_pad,
1827                                     char *base_data,
1828                                     char **ppdata,
1829                                     char *end_data,
1830                                     uint64_t *last_entry_off)
1831 {
1832         char *p, *q, *pdata = *ppdata;
1833         uint32_t reskey=0;
1834         uint64_t file_size = 0;
1835         uint64_t allocation_size = 0;
1836         uint64_t file_id = 0;
1837         size_t len = 0;
1838         struct timespec mdate_ts = {0};
1839         struct timespec adate_ts = {0};
1840         struct timespec cdate_ts = {0};
1841         struct timespec create_date_ts = {0};
1842         time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1843         char *nameptr;
1844         char *last_entry_ptr;
1845         bool was_8_3;
1846         int off;
1847         int pad = 0;
1848         NTSTATUS status;
1849         struct readdir_attr_data *readdir_attr_data = NULL;
1850
1851         if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
1852                 file_size = get_file_size_stat(&smb_fname->st);
1853         }
1854         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
1855
1856         status = SMB_VFS_READDIR_ATTR(conn, smb_fname, ctx, &readdir_attr_data);
1857         if (!NT_STATUS_IS_OK(status)) {
1858                 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_SUPPORTED, status)) {
1859                         return status;
1860                 }
1861         }
1862
1863         file_id = SMB_VFS_FS_FILE_ID(conn, &smb_fname->st);
1864
1865         mdate_ts = smb_fname->st.st_ex_mtime;
1866         adate_ts = smb_fname->st.st_ex_atime;
1867         create_date_ts = get_create_timespec(conn, NULL, smb_fname);
1868         cdate_ts = get_change_timespec(conn, NULL, smb_fname);
1869
1870         if (lp_dos_filetime_resolution(SNUM(conn))) {
1871                 dos_filetime_timespec(&create_date_ts);
1872                 dos_filetime_timespec(&mdate_ts);
1873                 dos_filetime_timespec(&adate_ts);
1874                 dos_filetime_timespec(&cdate_ts);
1875         }
1876
1877         create_date = convert_timespec_to_time_t(create_date_ts);
1878         mdate = convert_timespec_to_time_t(mdate_ts);
1879         adate = convert_timespec_to_time_t(adate_ts);
1880
1881         /* align the record */
1882         SMB_ASSERT(align >= 1);
1883
1884         off = (int)PTR_DIFF(pdata, base_data);
1885         pad = (off + (align-1)) & ~(align-1);
1886         pad -= off;
1887
1888         if (pad && pad > space_remaining) {
1889                 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1890                         "for padding (wanted %u, had %d)\n",
1891                         (unsigned int)pad,
1892                         space_remaining ));
1893                 return STATUS_MORE_ENTRIES; /* Not finished - just out of space */
1894         }
1895
1896         off += pad;
1897         /* initialize padding to 0 */
1898         if (pad) {
1899                 memset(pdata, 0, pad);
1900         }
1901         space_remaining -= pad;
1902
1903         DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
1904                 space_remaining ));
1905
1906         pdata += pad;
1907         p = pdata;
1908         last_entry_ptr = p;
1909
1910         pad = 0;
1911         off = 0;
1912
1913         switch (info_level) {
1914         case SMB_FIND_INFO_STANDARD:
1915                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1916                 if(requires_resume_key) {
1917                         SIVAL(p,0,reskey);
1918                         p += 4;
1919                 }
1920                 srv_put_dos_date2(p,0,create_date);
1921                 srv_put_dos_date2(p,4,adate);
1922                 srv_put_dos_date2(p,8,mdate);
1923                 SIVAL(p,12,(uint32_t)file_size);
1924                 SIVAL(p,16,(uint32_t)allocation_size);
1925                 SSVAL(p,20,mode);
1926                 p += 23;
1927                 nameptr = p;
1928                 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1929                         p += ucs2_align(base_data, p, 0);
1930                 }
1931                 status = srvstr_push(base_data, flags2, p,
1932                                   fname, PTR_DIFF(end_data, p),
1933                                   STR_TERMINATE, &len);
1934                 if (!NT_STATUS_IS_OK(status)) {
1935                         return status;
1936                 }
1937                 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1938                         if (len > 2) {
1939                                 SCVAL(nameptr, -1, len - 2);
1940                         } else {
1941                                 SCVAL(nameptr, -1, 0);
1942                         }
1943                 } else {
1944                         if (len > 1) {
1945                                 SCVAL(nameptr, -1, len - 1);
1946                         } else {
1947                                 SCVAL(nameptr, -1, 0);
1948                         }
1949                 }
1950                 p += len;
1951                 break;
1952
1953         case SMB_FIND_EA_SIZE:
1954                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
1955                 if (requires_resume_key) {
1956                         SIVAL(p,0,reskey);
1957                         p += 4;
1958                 }
1959                 srv_put_dos_date2(p,0,create_date);
1960                 srv_put_dos_date2(p,4,adate);
1961                 srv_put_dos_date2(p,8,mdate);
1962                 SIVAL(p,12,(uint32_t)file_size);
1963                 SIVAL(p,16,(uint32_t)allocation_size);
1964                 SSVAL(p,20,mode);
1965                 {
1966                         unsigned int ea_size = estimate_ea_size(conn, NULL,
1967                                                                 smb_fname);
1968                         SIVAL(p,22,ea_size); /* Extended attributes */
1969                 }
1970                 p += 27;
1971                 nameptr = p - 1;
1972                 status = srvstr_push(base_data, flags2,
1973                                   p, fname, PTR_DIFF(end_data, p),
1974                                   STR_TERMINATE | STR_NOALIGN, &len);
1975                 if (!NT_STATUS_IS_OK(status)) {
1976                         return status;
1977                 }
1978                 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1979                         if (len > 2) {
1980                                 len -= 2;
1981                         } else {
1982                                 len = 0;
1983                         }
1984                 } else {
1985                         if (len > 1) {
1986                                 len -= 1;
1987                         } else {
1988                                 len = 0;
1989                         }
1990                 }
1991                 SCVAL(nameptr,0,len);
1992                 p += len;
1993                 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1994                 break;
1995
1996         case SMB_FIND_EA_LIST:
1997         {
1998                 struct ea_list *file_list = NULL;
1999                 size_t ea_len = 0;
2000
2001                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
2002                 if (!name_list) {
2003                         return NT_STATUS_INVALID_PARAMETER;
2004                 }
2005                 if (requires_resume_key) {
2006                         SIVAL(p,0,reskey);
2007                         p += 4;
2008                 }
2009                 srv_put_dos_date2(p,0,create_date);
2010                 srv_put_dos_date2(p,4,adate);
2011                 srv_put_dos_date2(p,8,mdate);
2012                 SIVAL(p,12,(uint32_t)file_size);
2013                 SIVAL(p,16,(uint32_t)allocation_size);
2014                 SSVAL(p,20,mode);
2015                 p += 22; /* p now points to the EA area. */
2016
2017                 status = get_ea_list_from_file(ctx, conn, NULL,
2018                                                smb_fname,
2019                                                &ea_len, &file_list);
2020                 if (!NT_STATUS_IS_OK(status)) {
2021                         file_list = NULL;
2022                 }
2023                 name_list = ea_list_union(name_list, file_list, &ea_len);
2024
2025                 /* We need to determine if this entry will fit in the space available. */
2026                 /* Max string size is 255 bytes. */
2027                 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
2028                         DEBUG(9,("smbd_marshall_dir_entry: out of space "
2029                                 "(wanted %u, had %d)\n",
2030                                 (unsigned int)PTR_DIFF(p + 255 + ea_len,pdata),
2031                                 space_remaining ));
2032                         return STATUS_MORE_ENTRIES; /* Not finished - just out of space */
2033                 }
2034
2035                 /* Push the ea_data followed by the name. */
2036                 p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
2037                 nameptr = p;
2038                 status = srvstr_push(base_data, flags2,
2039                                   p + 1, fname, PTR_DIFF(end_data, p+1),
2040                                   STR_TERMINATE | STR_NOALIGN, &len);
2041                 if (!NT_STATUS_IS_OK(status)) {
2042                         return status;
2043                 }
2044                 if (flags2 & FLAGS2_UNICODE_STRINGS) {
2045                         if (len > 2) {
2046                                 len -= 2;
2047                         } else {
2048                                 len = 0;
2049                         }
2050                 } else {
2051                         if (len > 1) {
2052                                 len -= 1;
2053                         } else {
2054                                 len = 0;
2055                         }
2056                 }
2057                 SCVAL(nameptr,0,len);
2058                 p += len + 1;
2059                 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
2060                 break;
2061         }
2062
2063         case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2064                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
2065                 was_8_3 = mangle_is_8_3(fname, True, conn->params);
2066                 p += 4;
2067                 SIVAL(p,0,reskey); p += 4;
2068                 put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
2069                 put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
2070                 put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
2071                 put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
2072                 SOFF_T(p,0,file_size); p += 8;
2073                 SOFF_T(p,0,allocation_size); p += 8;
2074                 SIVAL(p,0,mode); p += 4;
2075                 q = p; p += 4; /* q is placeholder for name length. */
2076                 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
2077                         SIVAL(p, 0, IO_REPARSE_TAG_DFS);
2078                 } else {
2079                         unsigned int ea_size = estimate_ea_size(conn, NULL,
2080                                                                 smb_fname);
2081                         SIVAL(p,0,ea_size); /* Extended attributes */
2082                 }
2083                 p += 4;
2084                 /* Clear the short name buffer. This is
2085                  * IMPORTANT as not doing so will trigger
2086                  * a Win2k client bug. JRA.
2087                  */
2088                 if (!was_8_3 && check_mangled_names) {
2089                         char mangled_name[13]; /* mangled 8.3 name. */
2090                         if (!name_to_8_3(fname,mangled_name,True,
2091                                            conn->params)) {
2092                                 /* Error - mangle failed ! */
2093                                 memset(mangled_name,'\0',12);
2094                         }
2095                         mangled_name[12] = 0;
2096                         status = srvstr_push(base_data, flags2,
2097                                           p+2, mangled_name, 24,
2098                                           STR_UPPER|STR_UNICODE, &len);
2099                         if (!NT_STATUS_IS_OK(status)) {
2100                                 return status;
2101                         }
2102                         if (len < 24) {
2103                                 memset(p + 2 + len,'\0',24 - len);
2104                         }
2105                         SSVAL(p, 0, len);
2106                 } else {
2107                         memset(p,'\0',26);
2108                 }
2109                 p += 2 + 24;
2110                 status = srvstr_push(base_data, flags2, p,
2111                                   fname, PTR_DIFF(end_data, p),
2112                                   STR_TERMINATE_ASCII, &len);
2113                 if (!NT_STATUS_IS_OK(status)) {
2114                         return status;
2115                 }
2116                 SIVAL(q,0,len);
2117                 p += len;
2118
2119                 len = PTR_DIFF(p, pdata);
2120                 pad = (len + (align-1)) & ~(align-1);
2121                 /*
2122                  * offset to the next entry, the caller
2123                  * will overwrite it for the last entry
2124                  * that's why we always include the padding
2125                  */
2126                 SIVAL(pdata,0,pad);
2127                 /*
2128                  * set padding to zero
2129                  */
2130                 if (do_pad) {
2131                         memset(p, 0, pad - len);
2132                         p = pdata + pad;
2133                 } else {
2134                         p = pdata + len;
2135                 }
2136                 break;
2137
2138         case SMB_FIND_FILE_DIRECTORY_INFO:
2139                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
2140                 p += 4;
2141                 SIVAL(p,0,reskey); p += 4;
2142                 put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
2143                 put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
2144                 put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
2145                 put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
2146                 SOFF_T(p,0,file_size); p += 8;
2147                 SOFF_T(p,0,allocation_size); p += 8;
2148                 SIVAL(p,0,mode); p += 4;
2149                 status = srvstr_push(base_data, flags2,
2150                                   p + 4, fname, PTR_DIFF(end_data, p+4),
2151                                   STR_TERMINATE_ASCII, &len);
2152                 if (!NT_STATUS_IS_OK(status)) {
2153                         return status;
2154                 }
2155                 SIVAL(p,0,len);
2156                 p += 4 + len;
2157
2158                 len = PTR_DIFF(p, pdata);
2159                 pad = (len + (align-1)) & ~(align-1);
2160                 /*
2161                  * offset to the next entry, the caller
2162                  * will overwrite it for the last entry
2163                  * that's why we always include the padding
2164                  */
2165                 SIVAL(pdata,0,pad);
2166                 /*
2167                  * set padding to zero
2168                  */
2169                 if (do_pad) {
2170                         memset(p, 0, pad - len);
2171                         p = pdata + pad;
2172                 } else {
2173                         p = pdata + len;
2174                 }
2175                 break;
2176
2177         case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2178                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
2179                 p += 4;
2180                 SIVAL(p,0,reskey); p += 4;
2181                 put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
2182                 put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
2183                 put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
2184                 put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
2185                 SOFF_T(p,0,file_size); p += 8;
2186                 SOFF_T(p,0,allocation_size); p += 8;
2187                 SIVAL(p,0,mode); p += 4;
2188                 q = p; p += 4; /* q is placeholder for name length. */
2189                 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
2190                         SIVAL(p, 0, IO_REPARSE_TAG_DFS);
2191                 } else {
2192                         unsigned int ea_size = estimate_ea_size(conn, NULL,
2193                                                                 smb_fname);
2194                         SIVAL(p,0,ea_size); /* Extended attributes */
2195                 }
2196                 p +=4;
2197                 status = srvstr_push(base_data, flags2, p,
2198                                   fname, PTR_DIFF(end_data, p),
2199                                   STR_TERMINATE_ASCII, &len);
2200                 if (!NT_STATUS_IS_OK(status)) {
2201                         return status;
2202                 }
2203                 SIVAL(q, 0, len);
2204                 p += len;
2205
2206                 len = PTR_DIFF(p, pdata);
2207                 pad = (len + (align-1)) & ~(align-1);
2208                 /*
2209                  * offset to the next entry, the caller
2210                  * will overwrite it for the last entry
2211                  * that's why we always include the padding
2212                  */
2213                 SIVAL(pdata,0,pad);
2214                 /*
2215                  * set padding to zero
2216                  */
2217                 if (do_pad) {
2218                         memset(p, 0, pad - len);
2219                         p = pdata + pad;
2220                 } else {
2221                         p = pdata + len;
2222                 }
2223                 break;
2224
2225         case SMB_FIND_FILE_NAMES_INFO:
2226                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
2227                 p += 4;
2228                 SIVAL(p,0,reskey); p += 4;
2229                 p += 4;
2230                 /* this must *not* be null terminated or w2k gets in a loop trying to set an
2231                    acl on a dir (tridge) */
2232                 status = srvstr_push(base_data, flags2, p,
2233                                   fname, PTR_DIFF(end_data, p),
2234                                   STR_TERMINATE_ASCII, &len);
2235                 if (!NT_STATUS_IS_OK(status)) {
2236                         return status;
2237                 }
2238                 SIVAL(p, -4, len);
2239                 p += len;
2240
2241                 len = PTR_DIFF(p, pdata);
2242                 pad = (len + (align-1)) & ~(align-1);
2243                 /*
2244                  * offset to the next entry, the caller
2245                  * will overwrite it for the last entry
2246                  * that's why we always include the padding
2247                  */
2248                 SIVAL(pdata,0,pad);
2249                 /*
2250                  * set padding to zero
2251                  */
2252                 if (do_pad) {
2253                         memset(p, 0, pad - len);
2254                         p = pdata + pad;
2255                 } else {
2256                         p = pdata + len;
2257                 }
2258                 break;
2259
2260         case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2261                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
2262                 p += 4;
2263                 SIVAL(p,0,reskey); p += 4;
2264                 put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
2265                 put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
2266                 put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
2267                 put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
2268                 SOFF_T(p,0,file_size); p += 8;
2269                 SOFF_T(p,0,allocation_size); p += 8;
2270                 SIVAL(p,0,mode); p += 4;
2271                 q = p; p += 4; /* q is placeholder for name length. */
2272                 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
2273                         SIVAL(p, 0, IO_REPARSE_TAG_DFS);
2274                 } else {
2275                         unsigned int ea_size = estimate_ea_size(conn, NULL,
2276                                                                 smb_fname);
2277                         SIVAL(p,0,ea_size); /* Extended attributes */
2278                 }
2279                 p += 4;
2280                 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
2281                 SBVAL(p,0,file_id); p += 8;
2282                 status = srvstr_push(base_data, flags2, p,
2283                                   fname, PTR_DIFF(end_data, p),
2284                                   STR_TERMINATE_ASCII, &len);
2285                 if (!NT_STATUS_IS_OK(status)) {
2286                         return status;
2287                 }
2288                 SIVAL(q, 0, len);
2289                 p += len;
2290
2291                 len = PTR_DIFF(p, pdata);
2292                 pad = (len + (align-1)) & ~(align-1);
2293                 /*
2294                  * offset to the next entry, the caller
2295                  * will overwrite it for the last entry
2296                  * that's why we always include the padding
2297                  */
2298                 SIVAL(pdata,0,pad);
2299                 /*
2300                  * set padding to zero
2301                  */
2302                 if (do_pad) {
2303                         memset(p, 0, pad - len);
2304                         p = pdata + pad;
2305                 } else {
2306                         p = pdata + len;
2307                 }
2308                 break;
2309
2310         case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2311                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
2312                 was_8_3 = mangle_is_8_3(fname, True, conn->params);
2313                 p += 4;
2314                 SIVAL(p,0,reskey); p += 4;
2315                 put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
2316                 put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
2317                 put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
2318                 put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
2319                 SOFF_T(p,0,file_size); p += 8;
2320                 SOFF_T(p,0,allocation_size); p += 8;
2321                 SIVAL(p,0,mode); p += 4;
2322                 q = p; p += 4; /* q is placeholder for name length */
2323                 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
2324                         SIVAL(p, 0, IO_REPARSE_TAG_DFS);
2325                 } else if (readdir_attr_data &&
2326                            readdir_attr_data->type == RDATTR_AAPL) {
2327                         /*
2328                          * OS X specific SMB2 extension negotiated via
2329                          * AAPL create context: return max_access in
2330                          * ea_size field.
2331                          */
2332                         SIVAL(p, 0, readdir_attr_data->attr_data.aapl.max_access);
2333                 } else {
2334                         unsigned int ea_size = estimate_ea_size(conn, NULL,
2335                                                                 smb_fname);
2336                         SIVAL(p,0,ea_size); /* Extended attributes */
2337                 }
2338                 p += 4;
2339
2340                 if (readdir_attr_data &&
2341                     readdir_attr_data->type == RDATTR_AAPL) {
2342                         /*
2343                          * OS X specific SMB2 extension negotiated via
2344                          * AAPL create context: return resource fork
2345                          * length and compressed FinderInfo in
2346                          * shortname field.
2347                          *
2348                          * According to documentation short_name_len
2349                          * should be 0, but on the wire behaviour
2350                          * shows its set to 24 by clients.
2351                          */
2352                         SSVAL(p, 0, 24);
2353
2354                         /* Resourefork length */
2355                         SBVAL(p, 2, readdir_attr_data->attr_data.aapl.rfork_size);
2356
2357                         /* Compressed FinderInfo */
2358                         memcpy(p + 10, &readdir_attr_data->attr_data.aapl.finder_info, 16);
2359                 } else if (!was_8_3 && check_mangled_names) {
2360                         char mangled_name[13]; /* mangled 8.3 name. */
2361                         if (!name_to_8_3(fname,mangled_name,True,
2362                                         conn->params)) {
2363                                 /* Error - mangle failed ! */
2364                                 memset(mangled_name,'\0',12);
2365                         }
2366                         mangled_name[12] = 0;
2367                         status = srvstr_push(base_data, flags2,
2368                                           p+2, mangled_name, 24,
2369                                           STR_UPPER|STR_UNICODE, &len);
2370                         if (!NT_STATUS_IS_OK(status)) {
2371                                 return status;
2372                         }
2373                         SSVAL(p, 0, len);
2374                         if (len < 24) {
2375                                 memset(p + 2 + len,'\0',24 - len);
2376                         }
2377                         SSVAL(p, 0, len);
2378                 } else {
2379                         /* Clear the short name buffer. This is
2380                          * IMPORTANT as not doing so will trigger
2381                          * a Win2k client bug. JRA.
2382                          */
2383                         memset(p,'\0',26);
2384                 }
2385                 p += 26;
2386
2387                 /* Reserved ? */
2388                 if (readdir_attr_data &&
2389                     readdir_attr_data->type == RDATTR_AAPL) {
2390                         /*
2391                          * OS X specific SMB2 extension negotiated via
2392                          * AAPL create context: return UNIX mode in
2393                          * reserved field.
2394                          */
2395                         uint16_t aapl_mode = (uint16_t)readdir_attr_data->attr_data.aapl.unix_mode;
2396                         SSVAL(p, 0, aapl_mode);
2397                 } else {
2398                         SSVAL(p, 0, 0);
2399                 }
2400                 p += 2;
2401
2402                 SBVAL(p,0,file_id); p += 8;
2403                 status = srvstr_push(base_data, flags2, p,
2404                                   fname, PTR_DIFF(end_data, p),
2405                                   STR_TERMINATE_ASCII, &len);
2406                 if (!NT_STATUS_IS_OK(status)) {
2407                         return status;
2408                 }
2409                 SIVAL(q,0,len);
2410                 p += len;
2411
2412                 len = PTR_DIFF(p, pdata);
2413                 pad = (len + (align-1)) & ~(align-1);
2414                 /*
2415                  * offset to the next entry, the caller
2416                  * will overwrite it for the last entry
2417                  * that's why we always include the padding
2418                  */
2419                 SIVAL(pdata,0,pad);
2420                 /*
2421                  * set padding to zero
2422                  */
2423                 if (do_pad) {
2424                         memset(p, 0, pad - len);
2425                         p = pdata + pad;
2426                 } else {
2427                         p = pdata + len;
2428                 }
2429                 break;
2430
2431         /* CIFS UNIX Extension. */
2432
2433         case SMB_FIND_FILE_UNIX:
2434         case SMB_FIND_FILE_UNIX_INFO2:
2435                 p+= 4;
2436                 SIVAL(p,0,reskey); p+= 4;    /* Used for continuing search. */
2437
2438                 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
2439
2440                 if (info_level == SMB_FIND_FILE_UNIX) {
2441                         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
2442                         p = store_file_unix_basic(conn, p,
2443                                                 NULL, &smb_fname->st);
2444                         status = srvstr_push(base_data, flags2, p,
2445                                           fname, PTR_DIFF(end_data, p),
2446                                           STR_TERMINATE, &len);
2447                         if (!NT_STATUS_IS_OK(status)) {
2448                                 return status;
2449                         }
2450                 } else {
2451                         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
2452                         p = store_file_unix_basic_info2(conn, p,
2453                                                 NULL, &smb_fname->st);
2454                         nameptr = p;
2455                         p += 4;
2456                         status = srvstr_push(base_data, flags2, p, fname,
2457                                           PTR_DIFF(end_data, p), 0, &len);
2458                         if (!NT_STATUS_IS_OK(status)) {
2459                                 return status;
2460                         }
2461                         SIVAL(nameptr, 0, len);
2462                 }
2463
2464                 p += len;
2465
2466                 len = PTR_DIFF(p, pdata);
2467                 pad = (len + (align-1)) & ~(align-1);
2468                 /*
2469                  * offset to the next entry, the caller
2470                  * will overwrite it for the last entry
2471                  * that's why we always include the padding
2472                  */
2473                 SIVAL(pdata,0,pad);
2474                 /*
2475                  * set padding to zero
2476                  */
2477                 if (do_pad) {
2478                         memset(p, 0, pad - len);
2479                         p = pdata + pad;
2480                 } else {
2481                         p = pdata + len;
2482                 }
2483                 /* End of SMB_QUERY_FILE_UNIX_BASIC */
2484
2485                 break;
2486
2487         default:
2488                 return NT_STATUS_INVALID_LEVEL;
2489         }
2490
2491         if (PTR_DIFF(p,pdata) > space_remaining) {
2492                 DEBUG(9,("smbd_marshall_dir_entry: out of space "
2493                         "(wanted %u, had %d)\n",
2494                         (unsigned int)PTR_DIFF(p,pdata),
2495                         space_remaining ));
2496                 return STATUS_MORE_ENTRIES; /* Not finished - just out of space */
2497         }
2498
2499         /* Setup the last entry pointer, as an offset from base_data */
2500         *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
2501         /* Advance the data pointer to the next slot */
2502         *ppdata = p;
2503
2504         return NT_STATUS_OK;
2505 }
2506
2507 NTSTATUS smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
2508                                connection_struct *conn,
2509                                struct dptr_struct *dirptr,
2510                                uint16_t flags2,
2511                                const char *path_mask,
2512                                uint32_t dirtype,
2513                                int info_level,
2514                                int requires_resume_key,
2515                                bool dont_descend,
2516                                bool ask_sharemode,
2517                                bool get_dosmode,
2518                                uint8_t align,
2519                                bool do_pad,
2520                                char **ppdata,
2521                                char *base_data,
2522                                char *end_data,
2523                                int space_remaining,
2524                                struct smb_filename **_smb_fname,
2525                                bool *got_exact_match,
2526                                int *_last_entry_off,
2527                                struct ea_list *name_list,
2528                                struct file_id *file_id)
2529 {
2530         const char *p;
2531         const char *mask = NULL;
2532         long prev_dirpos = 0;
2533         uint32_t mode = 0;
2534         char *fname = NULL;
2535         struct smb_filename *smb_fname = NULL;
2536         struct smbd_dirptr_lanman2_state state;
2537         bool ok;
2538         uint64_t last_entry_off = 0;
2539         NTSTATUS status;
2540         enum mangled_names_options mangled_names;
2541         bool marshall_with_83_names;
2542
2543         mangled_names = lp_mangled_names(conn->params);
2544
2545         ZERO_STRUCT(state);
2546         state.conn = conn;
2547         state.info_level = info_level;
2548         if (mangled_names != MANGLED_NAMES_NO) {
2549                 state.check_mangled_names = true;
2550         }
2551         state.has_wild = dptr_has_wild(dirptr);
2552         state.got_exact_match = false;
2553
2554         *got_exact_match = false;
2555
2556         p = strrchr_m(path_mask,'/');
2557         if(p != NULL) {
2558                 if(p[1] == '\0') {
2559                         mask = "*.*";
2560                 } else {
2561                         mask = p+1;
2562                 }
2563         } else {
2564                 mask = path_mask;
2565         }
2566
2567         ok = smbd_dirptr_get_entry(ctx,
2568                                    dirptr,
2569                                    mask,
2570                                    dirtype,
2571                                    dont_descend,
2572                                    ask_sharemode,
2573                                    get_dosmode,
2574                                    smbd_dirptr_lanman2_match_fn,
2575                                    smbd_dirptr_lanman2_mode_fn,
2576                                    &state,
2577                                    &fname,
2578                                    &smb_fname,
2579                                    &mode,
2580                                    &prev_dirpos);
2581         if (!ok) {
2582                 return NT_STATUS_END_OF_FILE;
2583         }
2584
2585         *got_exact_match = state.got_exact_match;
2586
2587         marshall_with_83_names = (mangled_names == MANGLED_NAMES_YES);
2588
2589         status = smbd_marshall_dir_entry(ctx,
2590                                      conn,
2591                                      flags2,
2592                                      info_level,
2593                                      name_list,
2594                                      marshall_with_83_names,
2595                                      requires_resume_key,
2596                                      mode,
2597                                      fname,
2598                                      smb_fname,
2599                                      space_remaining,
2600                                      align,
2601                                      do_pad,
2602                                      base_data,
2603                                      ppdata,
2604                                      end_data,
2605                                      &last_entry_off);
2606         if (NT_STATUS_EQUAL(status, NT_STATUS_ILLEGAL_CHARACTER)) {
2607                 DEBUG(1,("Conversion error: illegal character: %s\n",
2608                          smb_fname_str_dbg(smb_fname)));
2609         }
2610
2611         if (file_id != NULL) {
2612                 *file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
2613         }
2614
2615         if (!NT_STATUS_IS_OK(status) &&
2616             !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2617         {
2618                 TALLOC_FREE(smb_fname);
2619                 TALLOC_FREE(fname);
2620                 return status;
2621         }
2622
2623         if (_smb_fname != NULL) {
2624                 struct smb_filename *name = NULL;
2625
2626                 name = synthetic_smb_fname(ctx,
2627                                            fname,
2628                                            NULL,
2629                                            &smb_fname->st,
2630                                            smb_fname->twrp,
2631                                            0);
2632                 if (name == NULL) {
2633                         TALLOC_FREE(smb_fname);
2634                         TALLOC_FREE(fname);
2635                         return NT_STATUS_NO_MEMORY;
2636                 }
2637                 *_smb_fname = name;
2638         }
2639
2640         TALLOC_FREE(smb_fname);
2641         TALLOC_FREE(fname);
2642
2643         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2644                 dptr_SeekDir(dirptr, prev_dirpos);
2645                 return status;
2646         }
2647
2648         *_last_entry_off = last_entry_off;
2649         return NT_STATUS_OK;
2650 }
2651
2652 static NTSTATUS get_lanman2_dir_entry(TALLOC_CTX *ctx,
2653                                 connection_struct *conn,
2654                                 struct dptr_struct *dirptr,
2655                                 uint16_t flags2,
2656                                 const char *path_mask,
2657                                 uint32_t dirtype,
2658                                 int info_level,
2659                                 bool requires_resume_key,
2660                                 bool dont_descend,
2661                                 bool ask_sharemode,
2662                                 char **ppdata,
2663                                 char *base_data,
2664                                 char *end_data,
2665                                 int space_remaining,
2666                                 bool *got_exact_match,
2667                                 int *last_entry_off,
2668                                 struct ea_list *name_list)
2669 {
2670         uint8_t align = 4;
2671         const bool do_pad = true;
2672
2673         if (info_level >= 1 && info_level <= 3) {
2674                 /* No alignment on earlier info levels. */
2675                 align = 1;
2676         }
2677
2678         return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
2679                                          path_mask, dirtype, info_level,
2680                                          requires_resume_key, dont_descend, ask_sharemode,
2681                                          true, align, do_pad,
2682                                          ppdata, base_data, end_data,
2683                                          space_remaining,
2684                                          NULL,
2685                                          got_exact_match,
2686                                          last_entry_off, name_list, NULL);
2687 }
2688
2689 /****************************************************************************
2690  Reply to a TRANS2_FINDFIRST.
2691 ****************************************************************************/
2692
2693 static void call_trans2findfirst(connection_struct *conn,
2694                                  struct smb_request *req,
2695                                  char **pparams, int total_params,
2696                                  char **ppdata, int total_data,
2697                                  unsigned int max_data_bytes)
2698 {
2699         /* We must be careful here that we don't return more than the
2700                 allowed number of data bytes. If this means returning fewer than
2701                 maxentries then so be it. We assume that the redirector has
2702                 enough room for the fixed number of parameter bytes it has
2703                 requested. */
2704         struct smb_filename *smb_dname = NULL;
2705         char *params = *pparams;
2706         char *pdata = *ppdata;
2707         char *data_end;
2708         uint32_t dirtype;
2709         int maxentries;
2710         uint16_t findfirst_flags;
2711         bool close_after_first;
2712         bool close_if_end;
2713         bool requires_resume_key;
2714         int info_level;
2715         char *directory = NULL;
2716         char *mask = NULL;
2717         char *p;
2718         int last_entry_off=0;
2719         int dptr_num = -1;
2720         int numentries = 0;
2721         int i;
2722         bool finished = False;
2723         bool dont_descend = False;
2724         bool out_of_space = False;
2725         int space_remaining;
2726         struct ea_list *ea_list = NULL;
2727         NTSTATUS ntstatus = NT_STATUS_OK;
2728         bool ask_sharemode = lp_smbd_search_ask_sharemode(SNUM(conn));
2729         struct smbd_server_connection *sconn = req->sconn;
2730         uint32_t ucf_flags = UCF_ALWAYS_ALLOW_WCARD_LCOMP |
2731                         ucf_flags_from_smb_request(req);
2732         bool backup_priv = false;
2733         bool as_root = false;
2734         files_struct *fsp = NULL;
2735         const struct loadparm_substitution *lp_sub =
2736                 loadparm_s3_global_substitution();
2737         int ret;
2738
2739         if (total_params < 13) {
2740                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2741                 goto out;
2742         }
2743
2744         dirtype = SVAL(params,0);
2745         maxentries = SVAL(params,2);
2746         findfirst_flags = SVAL(params,4);
2747         close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
2748         close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2749         requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2750         backup_priv = ((findfirst_flags & FLAG_TRANS2_FIND_BACKUP_INTENT) &&
2751                                 security_token_has_privilege(get_current_nttok(conn),
2752                                                 SEC_PRIV_BACKUP));
2753
2754         info_level = SVAL(params,6);
2755
2756         DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2757 close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_data_bytes = %d\n",
2758                 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
2759                 (int)backup_priv,
2760                 info_level, max_data_bytes));
2761
2762         if (!maxentries) {
2763                 /* W2K3 seems to treat zero as 1. */
2764                 maxentries = 1;
2765         }
2766
2767         switch (info_level) {
2768                 case SMB_FIND_INFO_STANDARD:
2769                 case SMB_FIND_EA_SIZE:
2770                 case SMB_FIND_EA_LIST:
2771                 case SMB_FIND_FILE_DIRECTORY_INFO:
2772                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2773                 case SMB_FIND_FILE_NAMES_INFO:
2774                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2775                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2776                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2777                         break;
2778                 case SMB_FIND_FILE_UNIX:
2779                 case SMB_FIND_FILE_UNIX_INFO2:
2780                         if (!lp_unix_extensions()) {
2781                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2782                                 goto out;
2783                         }
2784                         break;
2785                 default:
2786                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2787                         goto out;
2788         }
2789
2790         if (req->posix_pathnames) {
2791                 /* Always use filesystem for UNIX mtime query. */
2792                 ask_sharemode = false;
2793         }
2794
2795         if (req->posix_pathnames) {
2796                 srvstr_get_path_posix(talloc_tos(),
2797                                 params,
2798                                 req->flags2,
2799                                 &directory,
2800                                 params+12,
2801                                 total_params - 12,
2802                                 STR_TERMINATE,
2803                                 &ntstatus);
2804         } else {
2805                 srvstr_get_path(talloc_tos(),
2806                                 params,
2807                                 req->flags2,
2808                                 &directory,
2809                                 params+12,
2810                                 total_params - 12,
2811                                 STR_TERMINATE,
2812                                 &ntstatus);
2813         }
2814         if (!NT_STATUS_IS_OK(ntstatus)) {
2815                 reply_nterror(req, ntstatus);
2816                 goto out;
2817         }
2818
2819         if (backup_priv) {
2820                 become_root();
2821                 as_root = true;
2822                 ntstatus = filename_convert_with_privilege(talloc_tos(),
2823                                 conn,
2824                                 req,
2825                                 directory,
2826                                 ucf_flags,
2827                                 &smb_dname);
2828         } else {
2829                 ntstatus = filename_convert(talloc_tos(), conn,
2830                                     directory,
2831                                     ucf_flags,
2832                                     0,
2833                                     &smb_dname);
2834         }
2835
2836         if (!NT_STATUS_IS_OK(ntstatus)) {
2837                 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
2838                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2839                                         ERRSRV, ERRbadpath);
2840                         goto out;
2841                 }
2842                 reply_nterror(req, ntstatus);
2843                 goto out;
2844         }
2845
2846         mask = get_original_lcomp(talloc_tos(),
2847                                 conn,
2848                                 directory,
2849                                 ucf_flags);
2850         if (mask == NULL) {
2851                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2852                 goto out;
2853         }
2854
2855         directory = smb_dname->base_name;
2856
2857         p = strrchr_m(directory,'/');
2858         if(p == NULL) {
2859                 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2860                 if((directory[0] == '.') && (directory[1] == '\0')) {
2861                         mask = talloc_strdup(talloc_tos(),"*");
2862                         if (!mask) {
2863                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2864                                 goto out;
2865                         }
2866                 }
2867         } else {
2868                 *p = 0;
2869         }
2870
2871         if (p == NULL || p == directory) {
2872                 struct smb_filename *old_name = smb_dname;
2873
2874                 /* Ensure we don't have a directory name of "". */
2875                 smb_dname = synthetic_smb_fname(talloc_tos(),
2876                                                 ".",
2877                                                 NULL,
2878                                                 &old_name->st,
2879                                                 old_name->twrp,
2880                                                 old_name->flags);
2881                 TALLOC_FREE(old_name);
2882                 if (smb_dname == NULL) {
2883                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2884                         goto out;
2885                 }
2886                 directory = smb_dname->base_name;
2887         }
2888
2889         DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
2890
2891         if (info_level == SMB_FIND_EA_LIST) {
2892                 uint32_t ea_size;
2893
2894                 if (total_data < 4) {
2895                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2896                         goto out;
2897                 }
2898
2899                 ea_size = IVAL(pdata,0);
2900                 if (ea_size != total_data) {
2901                         DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2902 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2903                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2904                         goto out;
2905                 }
2906
2907                 if (!lp_ea_support(SNUM(conn))) {
2908                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
2909                         goto out;
2910                 }
2911
2912                 /* Pull out the list of names. */
2913                 ea_list = read_ea_name_list(talloc_tos(), pdata + 4, ea_size - 4);
2914                 if (!ea_list) {
2915                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2916                         goto out;
2917                 }
2918         }
2919
2920         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
2921                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2922                 goto out;
2923         }
2924
2925         *ppdata = (char *)SMB_REALLOC(
2926                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2927         if(*ppdata == NULL ) {
2928                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2929                 goto out;
2930         }
2931         pdata = *ppdata;
2932         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2933         /*
2934          * squash valgrind "writev(vector[...]) points to uninitialised byte(s)"
2935          * error.
2936          */
2937         memset(pdata + total_data, 0, ((max_data_bytes + DIR_ENTRY_SAFETY_MARGIN) - total_data));
2938         /* Realloc the params space */
2939         *pparams = (char *)SMB_REALLOC(*pparams, 10);
2940         if (*pparams == NULL) {
2941                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2942                 goto out;
2943         }
2944         params = *pparams;
2945
2946         /*
2947          * As we've cut off the last component from
2948          * smb_fname we need to re-stat smb_dname
2949          * so FILE_OPEN disposition knows the directory
2950          * exists.
2951          */
2952         if (req->posix_pathnames) {
2953                 ret = SMB_VFS_LSTAT(conn, smb_dname);
2954         } else {
2955                 ret = SMB_VFS_STAT(conn, smb_dname);
2956         }
2957
2958         if (ret == -1) {
2959                 ntstatus = map_nt_error_from_unix(errno);
2960                 reply_nterror(req, ntstatus);
2961                 goto out;
2962         }
2963
2964         /*
2965          * Open an fsp on this directory for the dptr.
2966          */
2967         ntstatus = SMB_VFS_CREATE_FILE(
2968                         conn, /* conn */
2969                         req, /* req */
2970                         smb_dname, /* dname */
2971                         FILE_LIST_DIRECTORY, /* access_mask */
2972                         FILE_SHARE_READ|
2973                         FILE_SHARE_WRITE, /* share_access */
2974                         FILE_OPEN, /* create_disposition*/
2975                         FILE_DIRECTORY_FILE, /* create_options */
2976                         FILE_ATTRIBUTE_DIRECTORY,/* file_attributes */
2977                         NO_OPLOCK, /* oplock_request */
2978                         NULL, /* lease */
2979                         0, /* allocation_size */
2980                         0, /* private_flags */
2981                         NULL, /* sd */
2982                         NULL, /* ea_list */
2983                         &fsp, /* result */
2984                         NULL, /* pinfo */
2985                         NULL, /* in_context */
2986                         NULL);/* out_context */
2987
2988         if (!NT_STATUS_IS_OK(ntstatus)) {
2989                 DBG_ERR("failed to open directory %s\n",
2990                         smb_fname_str_dbg(smb_dname));
2991                 reply_nterror(req, ntstatus);
2992                 goto out;
2993         }
2994
2995         /* Save the wildcard match and attribs we are using on this directory -
2996                 needed as lanman2 assumes these are being saved between calls */
2997
2998         ntstatus = dptr_create(conn,
2999                                 req,
3000                                 fsp, /* fsp */
3001                                 False,
3002                                 True,
3003                                 req->smbpid,
3004                                 mask,
3005                                 dirtype,
3006                                 &fsp->dptr);
3007
3008         if (!NT_STATUS_IS_OK(ntstatus)) {
3009                 /*
3010                  * Use NULL here for the first parameter (req)
3011                  * as this is not a client visible handle so
3012                  * can'tbe part of an SMB1 chain.
3013                  */
3014                 close_file(NULL, fsp, NORMAL_CLOSE);
3015                 fsp = NULL;
3016                 reply_nterror(req, ntstatus);
3017                 goto out;
3018         }
3019
3020         if (backup_priv) {
3021                 /* Remember this in case we have
3022                    to do a findnext. */
3023                 dptr_set_priv(fsp->dptr);
3024         }
3025
3026         dptr_num = dptr_dnum(fsp->dptr);
3027         DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
3028
3029         /* We don't need to check for VOL here as this is returned by
3030                 a different TRANS2 call. */
3031
3032         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
3033                  directory,lp_dont_descend(talloc_tos(), lp_sub, SNUM(conn))));
3034         if (in_list(directory,
3035                     lp_dont_descend(talloc_tos(), lp_sub, SNUM(conn)),
3036                         conn->case_sensitive)) {
3037                 dont_descend = True;
3038         }
3039
3040         p = pdata;
3041         space_remaining = max_data_bytes;
3042         out_of_space = False;
3043
3044         for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
3045                 bool got_exact_match = False;
3046
3047                 /* this is a heuristic to avoid seeking the dirptr except when
3048                         absolutely necessary. It allows for a filename of about 40 chars */
3049                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
3050                         out_of_space = True;
3051                         finished = False;
3052                 } else {
3053                         ntstatus = get_lanman2_dir_entry(talloc_tos(),
3054                                         conn,
3055                                         fsp->dptr,
3056                                         req->flags2,
3057                                         mask,dirtype,info_level,
3058                                         requires_resume_key,dont_descend,
3059                                         ask_sharemode,
3060                                         &p,pdata,data_end,
3061                                         space_remaining,
3062                                         &got_exact_match,
3063                                         &last_entry_off, ea_list);
3064                         if (NT_STATUS_EQUAL(ntstatus,
3065                                         NT_STATUS_ILLEGAL_CHARACTER)) {
3066                                 /*
3067                                  * Bad character conversion on name. Ignore this
3068                                  * entry.
3069                                  */
3070                                 continue;
3071                         }
3072                         if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
3073                                 out_of_space = true;
3074                         } else {
3075                                 finished = !NT_STATUS_IS_OK(ntstatus);
3076                         }
3077                 }
3078
3079                 if (!finished && !out_of_space)
3080                         numentries++;
3081
3082                 /*
3083                  * As an optimisation if we know we aren't looking
3084                  * for a wildcard name (ie. the name matches the wildcard exactly)
3085                  * then we can finish on any (first) match.
3086                  * This speeds up large directory searches. JRA.
3087                  */
3088
3089                 if(got_exact_match)
3090                         finished = True;
3091
3092                 /* Ensure space_remaining never goes -ve. */
3093                 if (PTR_DIFF(p,pdata) > max_data_bytes) {
3094                         space_remaining = 0;
3095                         out_of_space = true;
3096                 } else {
3097                         space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
3098                 }
3099         }
3100
3101         /* Check if we can close the dirptr */
3102         if(close_after_first || (finished && close_if_end)) {
3103                 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
3104                 dptr_num = -1;
3105                 close_file(NULL, fsp, NORMAL_CLOSE);
3106                 fsp = NULL;
3107         }
3108
3109         /*
3110          * If there are no matching entries we must return ERRDOS/ERRbadfile -
3111          * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
3112          * the protocol level is less than NT1. Tested with smbclient. JRA.
3113          * This should fix the OS/2 client bug #2335.
3114          */
3115
3116         if(numentries == 0) {
3117                 dptr_num = -1;
3118                 /*
3119                  * We may have already closed the file in the
3120                  * close_after_first or finished case above.
3121                  */
3122                 if (fsp != NULL) {
3123                         close_file(NULL, fsp, NORMAL_CLOSE);
3124                         fsp = NULL;
3125                 }
3126                 if (get_Protocol() < PROTOCOL_NT1) {
3127                         reply_force_doserror(req, ERRDOS, ERRnofiles);
3128                         goto out;
3129                 } else {
3130                         reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
3131                                         ERRDOS, ERRbadfile);
3132                         goto out;
3133                 }
3134         }
3135
3136         /* At this point pdata points to numentries directory entries. */
3137
3138         /* Set up the return parameter block */
3139         SSVAL(params,0,dptr_num);
3140         SSVAL(params,2,numentries);
3141         SSVAL(params,4,finished);
3142         SSVAL(params,6,0); /* Never an EA error */
3143         SSVAL(params,8,last_entry_off);
3144
3145         send_trans2_replies(conn, req, NT_STATUS_OK, params, 10, pdata, PTR_DIFF(p,pdata),
3146                             max_data_bytes);
3147
3148         if ((! *directory) && dptr_path(sconn, dptr_num)) {
3149                 directory = talloc_strdup(talloc_tos(),dptr_path(sconn, dptr_num));
3150                 if (!directory) {
3151                         reply_nterror(req, NT_STATUS_NO_MEMORY);
3152                 }
3153         }
3154
3155         DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
3156                 smb_fn_name(req->cmd),
3157                 mask, directory, dirtype, numentries ) );
3158
3159         /*
3160          * Force a name mangle here to ensure that the
3161          * mask as an 8.3 name is top of the mangled cache.
3162          * The reasons for this are subtle. Don't remove
3163          * this code unless you know what you are doing
3164          * (see PR#13758). JRA.
3165          */
3166
3167         if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
3168                 char mangled_name[13];
3169                 name_to_8_3(mask, mangled_name, True, conn->params);
3170         }
3171  out:
3172
3173         if (as_root) {
3174                 unbecome_root();
3175         }
3176
3177         TALLOC_FREE(smb_dname);
3178         return;
3179 }
3180
3181 /****************************************************************************
3182  Reply to a TRANS2_FINDNEXT.
3183 ****************************************************************************/
3184
3185 static void call_trans2findnext(connection_struct *conn,
3186                                 struct smb_request *req,
3187                                 char **pparams, int total_params,
3188                                 char **ppdata, int total_data,
3189                                 unsigned int max_data_bytes)
3190 {
3191         /* We must be careful here that we don't return more than the
3192                 allowed number of data bytes. If this means returning fewer than
3193                 maxentries then so be it. We assume that the redirector has
3194                 enough room for the fixed number of parameter bytes it has
3195                 requested. */
3196         char *params = *pparams;
3197         char *pdata = *ppdata;
3198         char *data_end;
3199         int dptr_num;
3200         int maxentries;
3201         uint16_t info_level;
3202         uint32_t resume_key;
3203         uint16_t findnext_flags;
3204         bool close_after_request;
3205         bool close_if_end;
3206         bool requires_resume_key;
3207         bool continue_bit;
3208         char *resume_name = NULL;
3209         const char *mask = NULL;
3210         const char *directory = NULL;
3211         char *p = NULL;
3212         uint16_t dirtype;
3213         int numentries = 0;
3214         int i, last_entry_off=0;
3215         bool finished = False;
3216         bool dont_descend = False;
3217         bool out_of_space = False;
3218         int space_remaining;
3219         struct ea_list *ea_list = NULL;
3220         NTSTATUS ntstatus = NT_STATUS_OK;
3221         bool ask_sharemode = lp_smbd_search_ask_sharemode(SNUM(conn));
3222         TALLOC_CTX *ctx = talloc_tos();
3223         struct smbd_server_connection *sconn = req->sconn;
3224         bool backup_priv = false; 
3225         bool as_root = false;
3226         files_struct *fsp = NULL;
3227         const struct loadparm_substitution *lp_sub =
3228                 loadparm_s3_global_substitution();
3229
3230         if (total_params < 13) {
3231                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3232                 return;
3233         }
3234
3235         dptr_num = SVAL(params,0);
3236         maxentries = SVAL(params,2);
3237         info_level = SVAL(params,4);
3238         resume_key = IVAL(params,6);
3239         findnext_flags = SVAL(params,10);
3240         close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
3241         close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
3242         requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
3243         continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
3244
3245         if (!continue_bit) {
3246                 /* We only need resume_name if continue_bit is zero. */
3247                 if (req->posix_pathnames) {
3248                         srvstr_get_path_posix(ctx,
3249                                 params,
3250                                 req->flags2,
3251                                 &resume_name,
3252                                 params+12,
3253                                 total_params - 12,
3254                                 STR_TERMINATE,
3255                                 &ntstatus);
3256                 } else {
3257                         srvstr_get_path(ctx,
3258                                 params,
3259                                 req->flags2,
3260                                 &resume_name,
3261                                 params+12,
3262                                 total_params - 12,
3263                                 STR_TERMINATE,
3264                                 &ntstatus);
3265                 }
3266                 if (!NT_STATUS_IS_OK(ntstatus)) {
3267                         /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
3268                            complain (it thinks we're asking for the directory above the shared
3269                            path or an invalid name). Catch this as the resume name is only compared, never used in
3270                            a file access. JRA. */
3271                         srvstr_pull_talloc(ctx, params, req->flags2,
3272                                 &resume_name, params+12,
3273                                 total_params - 12,
3274                                 STR_TERMINATE);
3275
3276                         if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
3277                                 reply_nterror(req, ntstatus);
3278                                 return;
3279                         }
3280                 }
3281         }
3282
3283         DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
3284 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
3285 resume_key = %d resume name = %s continue=%d level = %d\n",
3286                 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end, 
3287                 requires_resume_key, resume_key,
3288                 resume_name ? resume_name : "(NULL)", continue_bit, info_level));
3289
3290         if (!maxentries) {
3291                 /* W2K3 seems to treat zero as 1. */
3292                 maxentries = 1;
3293         }
3294
3295         switch (info_level) {
3296                 case SMB_FIND_INFO_STANDARD:
3297                 case SMB_FIND_EA_SIZE:
3298                 case SMB_FIND_EA_LIST:
3299                 case SMB_FIND_FILE_DIRECTORY_INFO:
3300                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
3301                 case SMB_FIND_FILE_NAMES_INFO:
3302                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
3303                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
3304                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
3305                         break;
3306                 case SMB_FIND_FILE_UNIX:
3307                 case SMB_FIND_FILE_UNIX_INFO2:
3308                         /* Always use filesystem for UNIX mtime query. */
3309                         ask_sharemode = false;
3310                         if (!lp_unix_extensions()) {
3311                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3312                                 return;
3313                         }
3314                         break;
3315                 default:
3316                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3317                         return;
3318         }
3319
3320         if (info_level == SMB_FIND_EA_LIST) {
3321                 uint32_t ea_size;
3322
3323                 if (total_data < 4) {
3324                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3325                         return;
3326                 }
3327
3328                 ea_size = IVAL(pdata,0);
3329                 if (ea_size != total_data) {
3330                         DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
3331 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
3332                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3333                         return;
3334                 }
3335
3336                 if (!lp_ea_support(SNUM(conn))) {
3337                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
3338                         return;
3339                 }
3340
3341                 /* Pull out the list of names. */
3342                 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
3343                 if (!ea_list) {
3344                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3345                         return;
3346                 }
3347         }
3348
3349         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
3350                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3351                 return;
3352         }
3353
3354         *ppdata = (char *)SMB_REALLOC(
3355                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
3356         if(*ppdata == NULL) {
3357                 reply_nterror(req, NT_STATUS_NO_MEMORY);
3358                 return;
3359         }
3360
3361         pdata = *ppdata;
3362         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
3363
3364         /*
3365          * squash valgrind "writev(vector[...]) points to uninitialised byte(s)"
3366          * error.
3367          */
3368         memset(pdata + total_data, 0, (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN) - total_data);
3369         /* Realloc the params space */
3370         *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
3371         if(*pparams == NULL ) {
3372                 reply_nterror(req, NT_STATUS_NO_MEMORY);
3373                 return;
3374         }
3375
3376         params = *pparams;
3377
3378         /* Check that the dptr is valid */
3379         fsp = dptr_fetch_lanman2_fsp(sconn, dptr_num);
3380         if (fsp == NULL) {
3381                 reply_nterror(req, STATUS_NO_MORE_FILES);
3382                 return;
3383         }
3384
3385         directory = dptr_path(sconn, dptr_num);
3386
3387         /* Get the wildcard mask from the dptr */
3388         if((mask = dptr_wcard(sconn, dptr_num))== NULL) {
3389                 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
3390                 reply_nterror(req, STATUS_NO_MORE_FILES);
3391                 return;
3392         }
3393
3394         /* Get the attr mask from the dptr */
3395         dirtype = dptr_attr(sconn, dptr_num);
3396
3397         backup_priv = dptr_get_priv(fsp->dptr);
3398
3399         DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld) "
3400                 "backup_priv = %d\n",
3401                 dptr_num, mask, dirtype,
3402                 (long)fsp->dptr,
3403                 dptr_TellDir(fsp->dptr),
3404                 (int)backup_priv));
3405
3406         /* We don't need to check for VOL here as this is returned by
3407                 a different TRANS2 call. */
3408
3409         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
3410                  directory,lp_dont_descend(ctx, lp_sub, SNUM(conn))));
3411         if (in_list(directory,lp_dont_descend(ctx, lp_sub, SNUM(conn)),conn->case_sensitive))
3412                 dont_descend = True;
3413
3414         p = pdata;
3415         space_remaining = max_data_bytes;
3416         out_of_space = False;
3417
3418         if (backup_priv) {
3419                 become_root();
3420                 as_root = true;
3421         }
3422
3423         /*
3424          * Seek to the correct position. We no longer use the resume key but
3425          * depend on the last file name instead.
3426          */
3427
3428         if(!continue_bit && resume_name && *resume_name) {
3429                 SMB_STRUCT_STAT st;
3430
3431                 long current_pos = 0;
3432                 /*
3433                  * Remember, name_to_8_3 is called by
3434                  * get_lanman2_dir_entry(), so the resume name
3435                  * could be mangled. Ensure we check the unmangled name.
3436                  */
3437
3438                 if (mangle_is_mangled(resume_name, conn->params)) {
3439                         char *new_resume_name = NULL;
3440                         mangle_lookup_name_from_8_3(ctx,
3441                                                 resume_name,
3442                                                 &new_resume_name,
3443                                                 conn->params);
3444                         if (new_resume_name) {
3445                                 resume_name = new_resume_name;
3446                         }
3447                 }
3448
3449                 /*
3450                  * Fix for NT redirector problem triggered by resume key indexes
3451                  * changing between directory scans. We now return a resume key of 0
3452                  * and instead look for the filename to continue from (also given
3453                  * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
3454                  * findfirst/findnext (as is usual) then the directory pointer
3455                  * should already be at the correct place.
3456                  */
3457
3458                 finished = !dptr_SearchDir(fsp->dptr, resume_name, &current_pos, &st);
3459         } /* end if resume_name && !continue_bit */
3460
3461         for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
3462                 bool got_exact_match = False;
3463
3464                 /* this is a heuristic to avoid seeking the fsp->dptr except when
3465                         absolutely necessary. It allows for a filename of about 40 chars */
3466                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
3467                         out_of_space = True;
3468                         finished = False;
3469                 } else {
3470                         ntstatus = get_lanman2_dir_entry(ctx,
3471                                                 conn,
3472                                                 fsp->dptr,
3473                                                 req->flags2,
3474                                                 mask,dirtype,info_level,
3475                                                 requires_resume_key,dont_descend,
3476                                                 ask_sharemode,
3477                                                 &p,pdata,data_end,
3478                                                 space_remaining,
3479                                                 &got_exact_match,
3480                                                 &last_entry_off, ea_list);
3481                         if (NT_STATUS_EQUAL(ntstatus,
3482                                         NT_STATUS_ILLEGAL_CHARACTER)) {
3483                                 /*
3484                                  * Bad character conversion on name. Ignore this
3485                                  * entry.
3486                                  */
3487                                 continue;
3488                         }
3489                         if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
3490                                 out_of_space = true;
3491                         } else {
3492                                 finished = !NT_STATUS_IS_OK(ntstatus);
3493                         }
3494                 }
3495
3496                 if (!finished && !out_of_space)
3497                         numentries++;
3498
3499                 /*
3500                  * As an optimisation if we know we aren't looking
3501                  * for a wildcard name (ie. the name matches the wildcard exactly)
3502                  * then we can finish on any (first) match.
3503                  * This speeds up large directory searches. JRA.
3504                  */
3505
3506                 if(got_exact_match)
3507                         finished = True;
3508
3509                 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
3510         }
3511
3512         DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
3513                 smb_fn_name(req->cmd),
3514                 mask, directory, dirtype, numentries ) );
3515
3516         /* Check if we can close the fsp->dptr */
3517         if(close_after_request || (finished && close_if_end)) {
3518                 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
3519                 dptr_num = -1;
3520                 close_file(NULL, fsp, NORMAL_CLOSE);
3521                 fsp = NULL;
3522         }
3523
3524         if (as_root) {
3525                 unbecome_root();
3526         }
3527
3528         /* Set up the return parameter block */
3529         SSVAL(params,0,numentries);
3530         SSVAL(params,2,finished);
3531         SSVAL(params,4,0); /* Never an EA error */
3532         SSVAL(params,6,last_entry_off);
3533
3534         send_trans2_replies(conn, req, NT_STATUS_OK, params, 8, pdata, PTR_DIFF(p,pdata),
3535                             max_data_bytes);
3536
3537         return;
3538 }
3539
3540 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
3541 {
3542         const struct loadparm_substitution *lp_sub =
3543                 loadparm_s3_global_substitution();
3544
3545         E_md4hash(lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),objid);
3546         return objid;
3547 }
3548
3549 static void samba_extended_info_version(struct smb_extended_info *extended_info)
3550 {
3551         SMB_ASSERT(extended_info != NULL);
3552
3553         extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
3554         extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
3555                                        | ((SAMBA_VERSION_MINOR & 0xff) << 16)
3556                                        | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
3557 #ifdef SAMBA_VERSION_REVISION
3558         extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
3559 #endif
3560         extended_info->samba_subversion = 0;
3561 #ifdef SAMBA_VERSION_RC_RELEASE
3562         extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
3563 #else
3564 #ifdef SAMBA_VERSION_PRE_RELEASE
3565         extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
3566 #endif
3567 #endif
3568 #ifdef SAMBA_VERSION_VENDOR_PATCH
3569         extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
3570 #endif
3571         extended_info->samba_gitcommitdate = 0;
3572 #ifdef SAMBA_VERSION_COMMIT_TIME
3573         unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_COMMIT_TIME);
3574 #endif
3575
3576         memset(extended_info->samba_version_string, 0,
3577                sizeof(extended_info->samba_version_string));
3578
3579         snprintf (extended_info->samba_version_string,
3580                   sizeof(extended_info->samba_version_string),
3581                   "%s", samba_version_string());
3582 }
3583
3584 NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
3585                          connection_struct *conn,
3586                          TALLOC_CTX *mem_ctx,
3587                          uint16_t info_level,
3588                          uint16_t flags2,
3589                          unsigned int max_data_bytes,
3590                          size_t *fixed_portion,
3591                          struct smb_filename *fname,
3592                          char **ppdata,
3593                          int *ret_data_len)
3594 {
3595         const struct loadparm_substitution *lp_sub =
3596                 loadparm_s3_global_substitution();
3597         char *pdata, *end_data;
3598         int data_len = 0;
3599         size_t len = 0;
3600         const char *vname = volume_label(talloc_tos(), SNUM(conn));
3601         int snum = SNUM(conn);
3602         const char *fstype = lp_fstype(SNUM(conn));
3603         const char *filename = NULL;
3604         const uint64_t bytes_per_sector = 512;
3605         uint32_t additional_flags = 0;
3606         struct smb_filename smb_fname;
3607         SMB_STRUCT_STAT st;
3608         NTSTATUS status = NT_STATUS_OK;
3609         uint64_t df_ret;
3610
3611         if (fname == NULL || fname->base_name == NULL) {
3612                 filename = ".";
3613         } else {
3614                 filename = fname->base_name;
3615         }
3616
3617         if (IS_IPC(conn)) {
3618                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
3619                         DEBUG(0,("smbd_do_qfsinfo: not an allowed "
3620                                 "info level (0x%x) on IPC$.\n",
3621                                 (unsigned int)info_level));
3622                         return NT_STATUS_ACCESS_DENIED;
3623                 }
3624         }
3625
3626         DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
3627
3628         smb_fname = (struct smb_filename) {
3629                 .base_name = discard_const_p(char, filename),
3630                 .flags = fname ? fname->flags : 0,
3631                 .twrp = fname ? fname->twrp : 0,
3632         };
3633
3634         if(info_level != SMB_FS_QUOTA_INFORMATION
3635            && SMB_VFS_STAT(conn, &smb_fname) != 0) {
3636                 DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
3637                 return map_nt_error_from_unix(errno);
3638         }
3639
3640         st = smb_fname.st;
3641
3642         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
3643                 return NT_STATUS_INVALID_PARAMETER;
3644         }
3645
3646         *ppdata = (char *)SMB_REALLOC(
3647                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
3648         if (*ppdata == NULL) {
3649                 return NT_STATUS_NO_MEMORY;
3650         }
3651
3652         pdata = *ppdata;
3653         memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
3654         end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
3655
3656         *fixed_portion = 0;
3657
3658         switch (info_level) {
3659                 case SMB_INFO_ALLOCATION:
3660                 {
3661                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
3662                         data_len = 18;
3663                         df_ret = get_dfree_info(conn, &smb_fname, &bsize,
3664                                                 &dfree, &dsize);
3665                         if (df_ret == (uint64_t)-1) {
3666                                 return map_nt_error_from_unix(errno);
3667                         }
3668
3669                         block_size = lp_block_size(snum);
3670                         if (bsize < block_size) {
3671                                 uint64_t factor = block_size/bsize;
3672                                 bsize = block_size;
3673                                 dsize /= factor;
3674                                 dfree /= factor;
3675                         }
3676                         if (bsize > block_size) {
3677                                 uint64_t factor = bsize/block_size;
3678                                 bsize = block_size;
3679                                 dsize *= factor;
3680                                 dfree *= factor;
3681                         }
3682                         sectors_per_unit = bsize/bytes_per_sector;
3683
3684                         DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
3685 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
3686                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
3687
3688                         /*
3689                          * For large drives, return max values and not modulo.
3690                          */
3691                         dsize = MIN(dsize, UINT32_MAX);
3692                         dfree = MIN(dfree, UINT32_MAX);
3693
3694                         SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
3695                         SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
3696                         SIVAL(pdata,l1_cUnit,dsize);
3697                         SIVAL(pdata,l1_cUnitAvail,dfree);
3698                         SSVAL(pdata,l1_cbSector,bytes_per_sector);
3699                         break;
3700                 }
3701
3702                 case SMB_INFO_VOLUME:
3703                         /* Return volume name */
3704                         /* 
3705                          * Add volume serial number - hash of a combination of
3706                          * the called hostname and the service name.
3707                          */
3708                         SIVAL(pdata,0,str_checksum(lp_servicename(talloc_tos(), lp_sub, snum)) ^ (str_checksum(get_local_machine_name())<<16) );
3709                         /*
3710                          * Win2k3 and previous mess this up by sending a name length
3711                          * one byte short. I believe only older clients (OS/2 Win9x) use
3712                          * this call so try fixing this by adding a terminating null to
3713                          * the pushed string. The change here was adding the STR_TERMINATE. JRA.
3714                          */
3715                         status = srvstr_push(
3716                                 pdata, flags2,
3717                                 pdata+l2_vol_szVolLabel, vname,
3718                                 PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
3719                                 STR_NOALIGN|STR_TERMINATE, &len);
3720                         if (!NT_STATUS_IS_OK(status)) {
3721                                 return status;
3722                         }
3723                         SCVAL(pdata,l2_vol_cch,len);
3724                         data_len = l2_vol_szVolLabel + len;
3725                         DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %u, name = %s\n",
3726                                  (unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
3727                                  (unsigned)len, vname));
3728                         break;
3729
3730                 case SMB_QUERY_FS_ATTRIBUTE_INFO:
3731                 case SMB_FS_ATTRIBUTE_INFORMATION:
3732
3733                         additional_flags = 0;
3734 #if defined(HAVE_SYS_QUOTAS)
3735                         additional_flags |= FILE_VOLUME_QUOTAS;
3736 #endif
3737
3738                         if(lp_nt_acl_support(SNUM(conn))) {
3739                                 additional_flags |= FILE_PERSISTENT_ACLS;
3740                         }
3741
3742                         /* Capabilities are filled in at connection time through STATVFS call */
3743                         additional_flags |= conn->fs_capabilities;
3744                         additional_flags |= lp_parm_int(conn->params->service,
3745                                                         "share", "fake_fscaps",
3746                                                         0);
3747
3748                         SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
3749                                 FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
3750                                 additional_flags); /* FS ATTRIBUTES */
3751
3752                         SIVAL(pdata,4,255); /* Max filename component length */
3753                         /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
3754                                 and will think we can't do long filenames */
3755                         status = srvstr_push(pdata, flags2, pdata+12, fstype,
3756                                           PTR_DIFF(end_data, pdata+12),
3757                                           STR_UNICODE, &len);
3758                         if (!NT_STATUS_IS_OK(status)) {
3759                                 return status;
3760                         }
3761                         SIVAL(pdata,8,len);
3762                         data_len = 12 + len;
3763                         if (max_data_bytes >= 16 && data_len > max_data_bytes) {
3764                                 /* the client only requested a portion of the
3765                                    file system name */
3766                                 data_len = max_data_bytes;
3767                                 status = STATUS_BUFFER_OVERFLOW;
3768                         }
3769                         *fixed_portion = 16;
3770                         break;
3771
3772                 case SMB_QUERY_FS_LABEL_INFO:
3773                 case SMB_FS_LABEL_INFORMATION:
3774                         status = srvstr_push(pdata, flags2, pdata+4, vname,
3775                                           PTR_DIFF(end_data, pdata+4), 0, &len);
3776                         if (!NT_STATUS_IS_OK(status)) {
3777                                 return status;
3778                         }
3779                         data_len = 4 + len;
3780                         SIVAL(pdata,0,len);
3781                         break;
3782
3783                 case SMB_QUERY_FS_VOLUME_INFO:      
3784                 case SMB_FS_VOLUME_INFORMATION:
3785
3786                         /* 
3787                          * Add volume serial number - hash of a combination of
3788                          * the called hostname and the service name.
3789                          */
3790                         SIVAL(pdata,8,str_checksum(lp_servicename(talloc_tos(), lp_sub, snum)) ^
3791                                 (str_checksum(get_local_machine_name())<<16));
3792
3793                         /* Max label len is 32 characters. */
3794                         status = srvstr_push(pdata, flags2, pdata+18, vname,
3795                                           PTR_DIFF(end_data, pdata+18),
3796                                           STR_UNICODE, &len);
3797                         if (!NT_STATUS_IS_OK(status)) {
3798                                 return status;
3799                         }
3800                         SIVAL(pdata,12,len);
3801                         data_len = 18+len;
3802
3803                         DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
3804                                 (int)strlen(vname),vname,
3805                                 lp_servicename(talloc_tos(), lp_sub, snum)));
3806                         if (max_data_bytes >= 24 && data_len > max_data_bytes) {
3807                                 /* the client only requested a portion of the
3808                                    volume label */
3809                                 data_len = max_data_bytes;
3810                                 status = STATUS_BUFFER_OVERFLOW;
3811                         }
3812                         *fixed_portion = 24;
3813                         break;
3814
3815                 case SMB_QUERY_FS_SIZE_INFO:
3816                 case SMB_FS_SIZE_INFORMATION:
3817                 {
3818                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
3819                         data_len = 24;
3820                         df_ret = get_dfree_info(conn, &smb_fname, &bsize,
3821                                                 &dfree, &dsize);
3822                         if (df_ret == (uint64_t)-1) {
3823                                 return map_nt_error_from_unix(errno);
3824                         }
3825                         block_size = lp_block_size(snum);
3826                         if (bsize < block_size) {
3827                                 uint64_t factor = block_size/bsize;
3828                                 bsize = block_size;
3829                                 dsize /= factor;
3830                                 dfree /= factor;
3831                         }
3832                         if (bsize > block_size) {
3833                                 uint64_t factor = bsize/block_size;
3834                                 bsize = block_size;
3835                                 dsize *= factor;
3836                                 dfree *= factor;
3837                         }
3838                         sectors_per_unit = bsize/bytes_per_sector;
3839                         DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3840 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
3841                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
3842                         SBIG_UINT(pdata,0,dsize);
3843                         SBIG_UINT(pdata,8,dfree);
3844                         SIVAL(pdata,16,sectors_per_unit);
3845                         SIVAL(pdata,20,bytes_per_sector);
3846                         *fixed_portion = 24;
3847                         break;
3848                 }
3849
3850                 case SMB_FS_FULL_SIZE_INFORMATION:
3851                 {
3852                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
3853                         data_len = 32;
3854                         df_ret = get_dfree_info(conn, &smb_fname, &bsize,
3855                                                 &dfree, &dsize);
3856                         if (df_ret == (uint64_t)-1) {
3857                                 return map_nt_error_from_unix(errno);
3858                         }
3859                         block_size = lp_block_size(snum);
3860                         if (bsize < block_size) {
3861                                 uint64_t factor = block_size/bsize;
3862                                 bsize = block_size;
3863                                 dsize /= factor;
3864                                 dfree /= factor;
3865                         }
3866                         if (bsize > block_size) {
3867                                 uint64_t factor = bsize/block_size;
3868                                 bsize = block_size;
3869                                 dsize *= factor;
3870                                 dfree *= factor;
3871                         }
3872                         sectors_per_unit = bsize/bytes_per_sector;
3873                         DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3874 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
3875                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
3876                         SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
3877                         SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
3878                         SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
3879                         SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
3880                         SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
3881                         *fixed_portion = 32;
3882                         break;
3883                 }
3884
3885                 case SMB_QUERY_FS_DEVICE_INFO:
3886                 case SMB_FS_DEVICE_INFORMATION:
3887                 {
3888                         uint32_t characteristics = FILE_DEVICE_IS_MOUNTED;
3889
3890                         if (!CAN_WRITE(conn)) {
3891                                 characteristics |= FILE_READ_ONLY_DEVICE;
3892                         }
3893                         data_len = 8;
3894                         SIVAL(pdata,0,FILE_DEVICE_DISK); /* dev type */
3895                         SIVAL(pdata,4,characteristics);
3896                         *fixed_portion = 8;
3897                         break;
3898                 }
3899
3900 #ifdef HAVE_SYS_QUOTAS
3901                 case SMB_FS_QUOTA_INFORMATION:
3902                 /* 
3903                  * what we have to send --metze:
3904                  *
3905                  * Unknown1:            24 NULL bytes
3906                  * Soft Quota Treshold: 8 bytes seems like uint64_t or so
3907                  * Hard Quota Limit:    8 bytes seems like uint64_t or so
3908                  * Quota Flags:         2 byte :
3909                  * Unknown3:            6 NULL bytes
3910                  *
3911                  * 48 bytes total
3912                  * 
3913                  * details for Quota Flags:
3914                  * 
3915                  * 0x0020 Log Limit: log if the user exceeds his Hard Quota
3916                  * 0x0010 Log Warn:  log if the user exceeds his Soft Quota
3917                  * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
3918                  * 0x0001 Enable Quotas: enable quota for this fs
3919                  *
3920                  */
3921                 {
3922                         /* we need to fake up a fsp here,
3923                          * because its not send in this call
3924                          */
3925                         files_struct fsp;
3926                         SMB_NTQUOTA_STRUCT quotas;
3927
3928                         ZERO_STRUCT(fsp);
3929                         ZERO_STRUCT(quotas);
3930
3931                         fsp.conn = conn;
3932                         fsp.fnum = FNUM_FIELD_INVALID;
3933
3934                         /* access check */
3935                         if (get_current_uid(conn) != 0) {
3936                                 DEBUG(0,("get_user_quota: access_denied "
3937                                          "service [%s] user [%s]\n",
3938                                          lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
3939                                          conn->session_info->unix_info->unix_name));
3940                                 return NT_STATUS_ACCESS_DENIED;
3941                         }
3942
3943                         status = vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE,
3944                                                  NULL, &quotas);
3945                         if (!NT_STATUS_IS_OK(status)) {
3946                                 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
3947                                 return status;
3948                         }
3949
3950                         data_len = 48;
3951
3952                         DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
3953                                   lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
3954
3955                         /* Unknown1 24 NULL bytes*/
3956                         SBIG_UINT(pdata,0,(uint64_t)0);
3957                         SBIG_UINT(pdata,8,(uint64_t)0);
3958                         SBIG_UINT(pdata,16,(uint64_t)0);
3959
3960                         /* Default Soft Quota 8 bytes */
3961                         SBIG_UINT(pdata,24,quotas.softlim);
3962
3963                         /* Default Hard Quota 8 bytes */
3964                         SBIG_UINT(pdata,32,quotas.hardlim);
3965
3966                         /* Quota flag 2 bytes */
3967                         SSVAL(pdata,40,quotas.qflags);
3968
3969                         /* Unknown3 6 NULL bytes */
3970                         SSVAL(pdata,42,0);
3971                         SIVAL(pdata,44,0);
3972
3973                         break;
3974                 }
3975 #endif /* HAVE_SYS_QUOTAS */
3976                 case SMB_FS_OBJECTID_INFORMATION:
3977                 {
3978                         unsigned char objid[16];
3979                         struct smb_extended_info extended_info;
3980                         memcpy(pdata,create_volume_objectid(conn, objid),16);
3981                         samba_extended_info_version (&extended_info);
3982                         SIVAL(pdata,16,extended_info.samba_magic);
3983                         SIVAL(pdata,20,extended_info.samba_version);
3984                         SIVAL(pdata,24,extended_info.samba_subversion);
3985                         SBIG_UINT(pdata,28,extended_info.samba_gitcommitdate);
3986                         memcpy(pdata+36,extended_info.samba_version_string,28);
3987                         data_len = 64;
3988                         break;
3989                 }
3990
3991                 case SMB_FS_SECTOR_SIZE_INFORMATION:
3992                 {
3993                         data_len = 28;
3994                         /*
3995                          * These values match a physical Windows Server 2012
3996                          * share backed by NTFS atop spinning rust.
3997                          */
3998                         DEBUG(5, ("SMB_FS_SECTOR_SIZE_INFORMATION:"));
3999                         /* logical_bytes_per_sector */
4000                         SIVAL(pdata, 0, bytes_per_sector);
4001                         /* phys_bytes_per_sector_atomic */
4002                         SIVAL(pdata, 4, bytes_per_sector);
4003                         /* phys_bytes_per_sector_perf */
4004                         SIVAL(pdata, 8, bytes_per_sector);
4005                         /* fs_effective_phys_bytes_per_sector_atomic */
4006                         SIVAL(pdata, 12, bytes_per_sector);
4007                         /* flags */
4008                         SIVAL(pdata, 16, SSINFO_FLAGS_ALIGNED_DEVICE
4009                                 | SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE);
4010                         /* byte_off_sector_align */
4011                         SIVAL(pdata, 20, 0);
4012                         /* byte_off_partition_align */
4013                         SIVAL(pdata, 24, 0);
4014                         *fixed_portion = 28;
4015                         break;
4016                 }
4017
4018
4019                 /*
4020                  * Query the version and capabilities of the CIFS UNIX extensions
4021                  * in use.
4022                  */
4023
4024                 case SMB_QUERY_CIFS_UNIX_INFO:
4025                 {
4026                         bool large_write = lp_min_receive_file_size() &&
4027                                         !srv_is_signing_active(xconn);
4028                         bool large_read = !srv_is_signing_active(xconn);
4029                         int encrypt_caps = 0;
4030
4031                         if (!lp_unix_extensions()) {
4032                                 return NT_STATUS_INVALID_LEVEL;
4033                         }
4034
4035                         switch (conn->encrypt_level) {
4036                         case SMB_SIGNING_OFF:
4037                                 encrypt_caps = 0;
4038                                 break;
4039                         case SMB_SIGNING_DESIRED:
4040                         case SMB_SIGNING_IF_REQUIRED:
4041                         case SMB_SIGNING_DEFAULT:
4042                                 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP;
4043                                 break;
4044                         case SMB_SIGNING_REQUIRED:
4045                                 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP|
4046                                                 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP;
4047                                 large_write = false;
4048                                 large_read = false;
4049                                 break;
4050                         }
4051
4052                         data_len = 12;
4053                         SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
4054                         SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
4055
4056                         /* We have POSIX ACLs, pathname, encryption, 
4057                          * large read/write, and locking capability. */
4058
4059                         SBIG_UINT(pdata,4,((uint64_t)(
4060                                         CIFS_UNIX_POSIX_ACLS_CAP|
4061                                         CIFS_UNIX_POSIX_PATHNAMES_CAP|
4062                                         CIFS_UNIX_FCNTL_LOCKS_CAP|
4063                                         CIFS_UNIX_EXTATTR_CAP|
4064                                         CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP|
4065                                         encrypt_caps|
4066                                         (large_read ? CIFS_UNIX_LARGE_READ_CAP : 0) |
4067                                         (large_write ?
4068                                         CIFS_UNIX_LARGE_WRITE_CAP : 0))));
4069                         break;
4070                 }
4071
4072                 case SMB_QUERY_POSIX_FS_INFO:
4073                 {
4074                         int rc;
4075                         vfs_statvfs_struct svfs;
4076
4077                         if (!lp_unix_extensions()) {
4078                                 return NT_STATUS_INVALID_LEVEL;
4079                         }
4080
4081                         rc = SMB_VFS_STATVFS(conn, &smb_fname, &svfs);
4082
4083                         if (!rc) {
4084                                 data_len = 56;
4085                                 SIVAL(pdata,0,svfs.OptimalTransferSize);
4086                                 SIVAL(pdata,4,svfs.BlockSize);
4087                                 SBIG_UINT(pdata,8,svfs.TotalBlocks);
4088                                 SBIG_UINT(pdata,16,svfs.BlocksAvail);
4089                                 SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
4090                                 SBIG_UINT(pdata,32,svfs.TotalFileNodes);
4091                                 SBIG_UINT(pdata,40,svfs.FreeFileNodes);
4092                                 SBIG_UINT(pdata,48,svfs.FsIdentifier);
4093                                 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
4094 #ifdef EOPNOTSUPP
4095                         } else if (rc == EOPNOTSUPP) {
4096                                 return NT_STATUS_INVALID_LEVEL;
4097 #endif /* EOPNOTSUPP */
4098                         } else {
4099                                 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4100                                 return NT_STATUS_DOS(ERRSRV, ERRerror);
4101                         }
4102                         break;
4103                 }
4104
4105                 case SMB_QUERY_POSIX_WHOAMI:
4106                 {
4107                         uint32_t flags = 0;
4108                         uint32_t sid_bytes;
4109                         int i;
4110
4111                         if (!lp_unix_extensions()) {
4112                                 return NT_STATUS_INVALID_LEVEL;
4113                         }
4114
4115                         if (max_data_bytes < 40) {
4116                                 return NT_STATUS_BUFFER_TOO_SMALL;
4117                         }
4118
4119                         if (security_session_user_level(conn->session_info, NULL) < SECURITY_USER) {
4120                                 flags |= SMB_WHOAMI_GUEST;
4121                         }
4122
4123                         /* NOTE: 8 bytes for UID/GID, irrespective of native
4124                          * platform size. This matches
4125                          * SMB_QUERY_FILE_UNIX_BASIC and friends.
4126                          */
4127                         data_len = 4 /* flags */
4128                             + 4 /* flag mask */
4129                             + 8 /* uid */
4130                             + 8 /* gid */
4131                             + 4 /* ngroups */
4132                             + 4 /* num_sids */
4133                             + 4 /* SID bytes */
4134                             + 4 /* pad/reserved */
4135                             + (conn->session_info->unix_token->ngroups * 8)
4136                                 /* groups list */
4137                             + (conn->session_info->security_token->num_sids *
4138                                     SID_MAX_SIZE)
4139                                 /* SID list */;
4140
4141                         SIVAL(pdata, 0, flags);
4142                         SIVAL(pdata, 4, SMB_WHOAMI_MASK);
4143                         SBIG_UINT(pdata, 8,
4144                                   (uint64_t)conn->session_info->unix_token->uid);
4145                         SBIG_UINT(pdata, 16,
4146                                   (uint64_t)conn->session_info->unix_token->gid);
4147
4148
4149                         if (data_len >= max_data_bytes) {
4150                                 /* Potential overflow, skip the GIDs and SIDs. */
4151
4152                                 SIVAL(pdata, 24, 0); /* num_groups */
4153                                 SIVAL(pdata, 28, 0); /* num_sids */
4154                                 SIVAL(pdata, 32, 0); /* num_sid_bytes */
4155                                 SIVAL(pdata, 36, 0); /* reserved */
4156
4157                                 data_len = 40;
4158                                 break;
4159                         }
4160
4161                         SIVAL(pdata, 24, conn->session_info->unix_token->ngroups);
4162                         SIVAL(pdata, 28, conn->session_info->security_token->num_sids);
4163
4164                         /* We walk the SID list twice, but this call is fairly
4165                          * infrequent, and I don't expect that it's performance
4166                          * sensitive -- jpeach
4167                          */
4168                         for (i = 0, sid_bytes = 0;
4169                              i < conn->session_info->security_token->num_sids; ++i) {
4170                                 sid_bytes += ndr_size_dom_sid(
4171                                         &conn->session_info->security_token->sids[i],
4172                                         0);
4173                         }
4174
4175                         /* SID list byte count */
4176                         SIVAL(pdata, 32, sid_bytes);
4177
4178                         /* 4 bytes pad/reserved - must be zero */
4179                         SIVAL(pdata, 36, 0);
4180                         data_len = 40;
4181
4182                         /* GID list */
4183                         for (i = 0; i < conn->session_info->unix_token->ngroups; ++i) {
4184                                 SBIG_UINT(pdata, data_len,
4185                                           (uint64_t)conn->session_info->unix_token->groups[i]);
4186                                 data_len += 8;
4187                         }
4188
4189                         /* SID list */
4190                         for (i = 0;
4191                             i < conn->session_info->security_token->num_sids; ++i) {
4192                                 int sid_len = ndr_size_dom_sid(
4193                                         &conn->session_info->security_token->sids[i],
4194                                         0);
4195
4196                                 sid_linearize((uint8_t *)(pdata + data_len),
4197                                               sid_len,
4198                                     &conn->session_info->security_token->sids[i]);
4199                                 data_len += sid_len;
4200                         }
4201
4202                         break;
4203                 }
4204
4205                 case SMB_MAC_QUERY_FS_INFO:
4206                         /*
4207                          * Thursby MAC extension... ONLY on NTFS filesystems
4208                          * once we do streams then we don't need this
4209                          */
4210                         if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
4211                                 data_len = 88;
4212                                 SIVAL(pdata,84,0x100); /* Don't support mac... */
4213                                 break;
4214                         }
4215
4216                         FALL_THROUGH;
4217                 default:
4218                         return NT_STATUS_INVALID_LEVEL;
4219         }
4220
4221         *ret_data_len = data_len;
4222         return status;
4223 }
4224
4225 static NTSTATUS smb_set_fsquota(connection_struct *conn,
4226                         struct smb_request *req,
4227                         files_struct *fsp,
4228                         const DATA_BLOB *qdata)
4229 {
4230         const struct loadparm_substitution *lp_sub =
4231                 loadparm_s3_global_substitution();
4232         NTSTATUS status;
4233         SMB_NTQUOTA_STRUCT quotas;
4234
4235         ZERO_STRUCT(quotas);
4236
4237         /* access check */
4238         if ((get_current_uid(conn) != 0) || !CAN_WRITE(conn)) {
4239                 DEBUG(3, ("set_fsquota: access_denied service [%s] user [%s]\n",
4240                           lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
4241                           conn->session_info->unix_info->unix_name));
4242                 return NT_STATUS_ACCESS_DENIED;
4243         }
4244
4245         if (!check_fsp_ntquota_handle(conn, req,
4246                                       fsp)) {
4247                 DEBUG(1, ("set_fsquota: no valid QUOTA HANDLE\n"));
4248                 return NT_STATUS_INVALID_HANDLE;
4249         }
4250
4251         /* note: normally there're 48 bytes,
4252          * but we didn't use the last 6 bytes for now
4253          * --metze
4254          */
4255         if (qdata->length < 42) {
4256                 DEBUG(0,("set_fsquota: requires total_data(%u) >= 42 bytes!\n",
4257                         (unsigned int)qdata->length));
4258                 return NT_STATUS_INVALID_PARAMETER;
4259         }
4260
4261         /* unknown_1 24 NULL bytes in pdata*/
4262
4263         /* the soft quotas 8 bytes (uint64_t)*/
4264         quotas.softlim = BVAL(qdata->data,24);
4265
4266         /* the hard quotas 8 bytes (uint64_t)*/
4267         quotas.hardlim = BVAL(qdata->data,32);
4268
4269         /* quota_flags 2 bytes **/
4270         quotas.qflags = SVAL(qdata->data,40);
4271
4272         /* unknown_2 6 NULL bytes follow*/
4273
4274         /* now set the quotas */
4275         if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
4276                 DEBUG(1, ("vfs_set_ntquota() failed for service [%s]\n",
4277                           lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4278                 status =  map_nt_error_from_unix(errno);
4279         } else {
4280                 status = NT_STATUS_OK;
4281         }
4282         return status;
4283 }
4284
4285 NTSTATUS smbd_do_setfsinfo(connection_struct *conn,
4286                                 struct smb_request *req,
4287                                 TALLOC_CTX *mem_ctx,
4288                                 uint16_t info_level,
4289                                 files_struct *fsp,
4290                                 const DATA_BLOB *pdata)
4291 {
4292         switch (info_level) {
4293                 case SMB_FS_QUOTA_INFORMATION:
4294                 {
4295                         return smb_set_fsquota(conn,
4296                                                 req,
4297                                                 fsp,
4298                                                 pdata);
4299                 }
4300
4301                 default:
4302                         break;
4303         }
4304         return NT_STATUS_INVALID_LEVEL;
4305 }
4306
4307 /****************************************************************************
4308  Reply to a TRANS2_QFSINFO (query filesystem info).
4309 ****************************************************************************/
4310
4311 static void call_trans2qfsinfo(connection_struct *conn,
4312                                struct smb_request *req,
4313                                char **pparams, int total_params,
4314                                char **ppdata, int total_data,
4315                                unsigned int max_data_bytes)
4316 {
4317         char *params = *pparams;
4318         uint16_t info_level;
4319         int data_len = 0;
4320         size_t fixed_portion;
4321         NTSTATUS status;
4322
4323         if (total_params < 2) {
4324                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4325                 return;
4326         }
4327
4328         info_level = SVAL(params,0);
4329
4330         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
4331                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
4332                         DEBUG(0,("call_trans2qfsinfo: encryption required "
4333                                 "and info level 0x%x sent.\n",
4334                                 (unsigned int)info_level));
4335                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4336                         return;
4337                 }
4338         }
4339
4340         DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
4341
4342         status = smbd_do_qfsinfo(req->xconn, conn, req,
4343                                  info_level,
4344                                  req->flags2,
4345                                  max_data_bytes,
4346                                  &fixed_portion,
4347                                  NULL,
4348                                  ppdata, &data_len);
4349         if (!NT_STATUS_IS_OK(status)) {
4350                 reply_nterror(req, status);
4351                 return;
4352         }
4353
4354         send_trans2_replies(conn, req, NT_STATUS_OK, params, 0, *ppdata, data_len,
4355                             max_data_bytes);
4356
4357         DEBUG( 4, ( "%s info_level = %d\n",
4358                     smb_fn_name(req->cmd), info_level) );
4359
4360         return;
4361 }
4362
4363 /****************************************************************************
4364  Reply to a TRANS2_SETFSINFO (set filesystem info).
4365 ****************************************************************************/
4366
4367 static void call_trans2setfsinfo(connection_struct *conn,
4368                                  struct smb_request *req,
4369                                  char **pparams, int total_params,
4370                                  char **ppdata, int total_data,
4371                                  unsigned int max_data_bytes)
4372 {
4373         const struct loadparm_substitution *lp_sub =
4374                 loadparm_s3_global_substitution();
4375         struct smbXsrv_connection *xconn = req->xconn;
4376         char *pdata = *ppdata;
4377         char *params = *pparams;
4378         uint16_t info_level;
4379
4380         DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",
4381                   lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4382
4383         /*  */
4384         if (total_params < 4) {
4385                 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
4386                         total_params));
4387                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4388                 return;
4389         }
4390
4391         info_level = SVAL(params,2);
4392
4393         if (IS_IPC(conn)) {
4394                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION &&
4395                                 info_level != SMB_SET_CIFS_UNIX_INFO) {
4396                         DEBUG(0,("call_trans2setfsinfo: not an allowed "
4397                                 "info level (0x%x) on IPC$.\n",
4398                                 (unsigned int)info_level));
4399                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4400                         return;
4401                 }
4402         }
4403
4404         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
4405                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
4406                         DEBUG(0,("call_trans2setfsinfo: encryption required "
4407                                 "and info level 0x%x sent.\n",
4408                                 (unsigned int)info_level));
4409                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4410                         return;
4411                 }
4412         }
4413
4414         switch(info_level) {
4415                 case SMB_SET_CIFS_UNIX_INFO:
4416                         if (!lp_unix_extensions()) {
4417                                 DEBUG(2,("call_trans2setfsinfo: "
4418                                         "SMB_SET_CIFS_UNIX_INFO is invalid with "
4419                                         "unix extensions off\n"));
4420                                 reply_nterror(req,
4421                                               NT_STATUS_INVALID_LEVEL);
4422                                 return;
4423                         }
4424
4425                         /* There should be 12 bytes of capabilities set. */
4426                         if (total_data < 12) {
4427                                 reply_nterror(
4428                                         req,
4429                                         NT_STATUS_INVALID_PARAMETER);
4430                                 return;
4431                         }
4432                         xconn->smb1.unix_info.client_major = SVAL(pdata,0);
4433                         xconn->smb1.unix_info.client_minor = SVAL(pdata,2);
4434                         xconn->smb1.unix_info.client_cap_low = IVAL(pdata,4);
4435                         xconn->smb1.unix_info.client_cap_high = IVAL(pdata,8);
4436                         /* Just print these values for now. */
4437                         DEBUG(10, ("call_trans2setfsinfo: set unix_info info. "
4438                                    "major = %u, minor = %u cap_low = 0x%x, "
4439                                    "cap_high = 0x%xn",
4440                                    (unsigned int)xconn->
4441                                    smb1.unix_info.client_major,
4442                                    (unsigned int)xconn->
4443                                    smb1.unix_info.client_minor,
4444                                    (unsigned int)xconn->
4445                                    smb1.unix_info.client_cap_low,
4446                                    (unsigned int)xconn->
4447                                    smb1.unix_info.client_cap_high));
4448
4449                         /* Here is where we must switch to posix pathname processing... */
4450                         if (xconn->smb1.unix_info.client_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
4451                                 lp_set_posix_pathnames();
4452                                 mangle_change_to_posix();
4453                         }
4454
4455                         if ((xconn->smb1.unix_info.client_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
4456                             !(xconn->smb1.unix_info.client_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
4457                                 /* Client that knows how to do posix locks,
4458                                  * but not posix open/mkdir operations. Set a
4459                                  * default type for read/write checks. */
4460
4461                                 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
4462
4463                         }
4464                         break;
4465
4466                 case SMB_REQUEST_TRANSPORT_ENCRYPTION:
4467                         {
4468                                 NTSTATUS status;
4469                                 size_t param_len = 0;
4470                                 size_t data_len = total_data;
4471
4472                                 if (!lp_unix_extensions()) {
4473                                         reply_nterror(
4474                                                 req,
4475                                                 NT_STATUS_INVALID_LEVEL);
4476                                         return;
4477                                 }
4478
4479                                 if (lp_server_smb_encrypt(SNUM(conn)) ==
4480                                     SMB_ENCRYPTION_OFF) {
4481                                         reply_nterror(
4482                                                 req,
4483                                                 NT_STATUS_NOT_SUPPORTED);
4484                                         return;
4485                                 }
4486
4487                                 if (xconn->smb1.echo_handler.trusted_fde) {
4488                                         DEBUG( 2,("call_trans2setfsinfo: "
4489                                                 "request transport encryption disabled"
4490                                                 "with 'fork echo handler = yes'\n"));
4491                                         reply_nterror(
4492                                                 req,
4493                                                 NT_STATUS_NOT_SUPPORTED);
4494                                         return;
4495                                 }
4496
4497                                 DEBUG( 4,("call_trans2setfsinfo: "
4498                                         "request transport encryption.\n"));
4499
4500                                 status = srv_request_encryption_setup(conn,
4501                                                                 (unsigned char **)ppdata,
4502                                                                 &data_len,
4503                                                                 (unsigned char **)pparams,
4504                                                                 &param_len);
4505
4506                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
4507                                                 !NT_STATUS_IS_OK(status)) {
4508                                         reply_nterror(req, status);
4509                                         return;
4510                                 }
4511
4512                                 send_trans2_replies(conn, req,
4513                                                 NT_STATUS_OK,
4514                                                 *pparams,
4515                                                 param_len,
4516                                                 *ppdata,
4517                                                 data_len,
4518                                                 max_data_bytes);
4519
4520                                 if (NT_STATUS_IS_OK(status)) {
4521                                         /* Server-side transport
4522                                          * encryption is now *on*. */
4523                                         status = srv_encryption_start(conn);
4524                                         if (!NT_STATUS_IS_OK(status)) {
4525                                                 char *reason = talloc_asprintf(talloc_tos(),
4526                                                                                "Failure in setting "
4527                                                                                "up encrypted transport: %s",
4528                                                                                nt_errstr(status));
4529                                                 exit_server_cleanly(reason);
4530                                         }
4531                                 }
4532                                 return;
4533                         }
4534
4535                 case SMB_FS_QUOTA_INFORMATION:
4536                         {
4537                                 NTSTATUS status;
4538                                 DATA_BLOB qdata = {
4539                                                 .data = (uint8_t *)pdata,
4540                                                 .length = total_data
4541                                 };
4542                                 files_struct *fsp = NULL;
4543                                 fsp = file_fsp(req, SVAL(params,0));
4544
4545                                 status = smb_set_fsquota(conn,
4546                                                         req,
4547                                                         fsp,
4548                                                         &qdata);
4549                                 if (!NT_STATUS_IS_OK(status)) {
4550                                         reply_nterror(req, status);
4551                                         return;
4552                                 }
4553                                 break;
4554                         }
4555                 default:
4556                         DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
4557                                 info_level));
4558                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
4559                         return;
4560                         break;
4561         }
4562
4563         /* 
4564          * sending this reply works fine, 
4565          * but I'm not sure it's the same 
4566          * like windows do...
4567          * --metze
4568          */
4569         reply_outbuf(req, 10, 0);
4570 }
4571
4572 #if defined(HAVE_POSIX_ACLS)
4573 /****************************************************************************
4574  Utility function to count the number of entries in a POSIX acl.
4575 ****************************************************************************/
4576
4577 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
4578 {
4579         unsigned int ace_count = 0;
4580         int entry_id = SMB_ACL_FIRST_ENTRY;
4581         SMB_ACL_ENTRY_T entry;
4582
4583         while ( posix_acl && (sys_acl_get_entry(posix_acl, entry_id, &entry) == 1)) {
4584                 /* get_next... */
4585                 if (entry_id == SMB_ACL_FIRST_ENTRY) {
4586                         entry_id = SMB_ACL_NEXT_ENTRY;
4587                 }
4588                 ace_count++;
4589         }
4590         return ace_count;
4591 }
4592
4593 /****************************************************************************
4594  Utility function to marshall a POSIX acl into wire format.
4595 ****************************************************************************/
4596
4597 static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
4598 {
4599         int entry_id = SMB_ACL_FIRST_ENTRY;
4600         SMB_ACL_ENTRY_T entry;
4601
4602         while ( posix_acl && (sys_acl_get_entry(posix_acl, entry_id, &entry) == 1)) {
4603                 SMB_ACL_TAG_T tagtype;
4604                 SMB_ACL_PERMSET_T permset;
4605                 unsigned char perms = 0;
4606                 unsigned int own_grp;
4607
4608                 /* get_next... */
4609                 if (entry_id == SMB_ACL_FIRST_ENTRY) {
4610                         entry_id = SMB_ACL_NEXT_ENTRY;
4611                 }
4612
4613                 if (sys_acl_get_tag_type(entry, &tagtype) == -1) {
4614                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
4615                         return False;
4616                 }
4617
4618                 if (sys_acl_get_permset(entry, &permset) == -1) {
4619                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
4620                         return False;
4621                 }
4622
4623                 perms |= (sys_acl_get_perm(permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
4624                 perms |= (sys_acl_get_perm(permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
4625                 perms |= (sys_acl_get_perm(permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
4626
4627                 SCVAL(pdata,1,perms);
4628
4629                 switch (tagtype) {
4630                         case SMB_ACL_USER_OBJ:
4631                                 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
4632                                 own_grp = (unsigned int)pst->st_ex_uid;
4633                                 SIVAL(pdata,2,own_grp);
4634                                 SIVAL(pdata,6,0);
4635                                 break;
4636                         case SMB_ACL_USER:
4637                                 {
4638                                         uid_t *puid = (uid_t *)sys_acl_get_qualifier(entry);
4639                                         if (!puid) {
4640                                                 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
4641                                                 return False;
4642                                         }
4643                                         own_grp = (unsigned int)*puid;
4644                                         SCVAL(pdata,0,SMB_POSIX_ACL_USER);
4645                                         SIVAL(pdata,2,own_grp);
4646                                         SIVAL(pdata,6,0);
4647                                         break;
4648                                 }
4649                         case SMB_ACL_GROUP_OBJ:
4650                                 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
4651                                 own_grp = (unsigned int)pst->st_ex_gid;
4652                                 SIVAL(pdata,2,own_grp);
4653                                 SIVAL(pdata,6,0);
4654                                 break;
4655                         case SMB_ACL_GROUP:
4656                                 {
4657                                         gid_t *pgid= (gid_t *)sys_acl_get_qualifier(entry);
4658                                         if (!pgid) {
4659                                                 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
4660                                                 return False;
4661                                         }
4662                                         own_grp = (unsigned int)*pgid;
4663                                         SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
4664                                         SIVAL(pdata,2,own_grp);
4665                                         SIVAL(pdata,6,0);
4666                                         break;
4667                                 }
4668                         case SMB_ACL_MASK:
4669                                 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
4670                                 SIVAL(pdata,2,0xFFFFFFFF);
4671                                 SIVAL(pdata,6,0xFFFFFFFF);
4672                                 break;
4673                         case SMB_ACL_OTHER:
4674                                 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
4675                                 SIVAL(pdata,2,0xFFFFFFFF);
4676                                 SIVAL(pdata,6,0xFFFFFFFF);
4677                                 break;
4678                         default:
4679                                 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
4680                                 return False;
4681                 }
4682                 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
4683         }
4684
4685         return True;
4686 }
4687 #endif
4688
4689 /****************************************************************************
4690  Store the FILE_UNIX_BASIC info.
4691 ****************************************************************************/
4692
4693 static char *store_file_unix_basic(connection_struct *conn,
4694                                 char *pdata,
4695                                 files_struct *fsp,
4696                                 const SMB_STRUCT_STAT *psbuf)
4697 {
4698         dev_t devno;
4699
4700         DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
4701         DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_ex_mode));
4702
4703         SOFF_T(pdata,0,get_file_size_stat(psbuf));             /* File size 64 Bit */
4704         pdata += 8;
4705
4706         SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
4707         pdata += 8;
4708
4709         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata, &psbuf->st_ex_ctime);       /* Change Time 64 Bit */
4710         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER ,pdata+8, &psbuf->st_ex_atime);     /* Last access time 64 Bit */
4711         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata+16, &psbuf->st_ex_mtime);    /* Last modification time 64 Bit */
4712         pdata += 24;
4713
4714         SIVAL(pdata,0,psbuf->st_ex_uid);               /* user id for the owner */
4715         SIVAL(pdata,4,0);
4716         pdata += 8;
4717
4718         SIVAL(pdata,0,psbuf->st_ex_gid);               /* group id of owner */
4719         SIVAL(pdata,4,0);
4720         pdata += 8;
4721
4722         SIVAL(pdata,0,unix_filetype(psbuf->st_ex_mode));
4723         pdata += 4;
4724
4725         if (S_ISBLK(psbuf->st_ex_mode) || S_ISCHR(psbuf->st_ex_mode)) {
4726                 devno = psbuf->st_ex_rdev;
4727         } else {
4728                 devno = psbuf->st_ex_dev;
4729         }
4730
4731         SIVAL(pdata,0,unix_dev_major(devno));   /* Major device number if type is device */
4732         SIVAL(pdata,4,0);
4733         pdata += 8;
4734
4735         SIVAL(pdata,0,unix_dev_minor(devno));   /* Minor device number if type is device */
4736         SIVAL(pdata,4,0);
4737         pdata += 8;
4738
4739         SINO_T_VAL(pdata, 0, psbuf->st_ex_ino);   /* inode number */
4740         pdata += 8;
4741
4742         SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode));     /* Standard UNIX file permissions */
4743         SIVAL(pdata,4,0);
4744         pdata += 8;
4745
4746         SIVAL(pdata,0,psbuf->st_ex_nlink);             /* number of hard links */
4747         SIVAL(pdata,4,0);
4748         pdata += 8;
4749
4750         return pdata;
4751 }
4752
4753 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
4754  * the chflags(2) (or equivalent) flags.
4755  *
4756  * XXX: this really should be behind the VFS interface. To do this, we would
4757  * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
4758  * Each VFS module could then implement its own mapping as appropriate for the
4759  * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
4760  */
4761 static const struct {unsigned stat_fflag; unsigned smb_fflag;}
4762         info2_flags_map[] =
4763 {
4764 #ifdef UF_NODUMP
4765     { UF_NODUMP, EXT_DO_NOT_BACKUP },
4766 #endif
4767
4768 #ifdef UF_IMMUTABLE
4769     { UF_IMMUTABLE, EXT_IMMUTABLE },
4770 #endif
4771
4772 #ifdef UF_APPEND
4773     { UF_APPEND, EXT_OPEN_APPEND_ONLY },
4774 #endif
4775
4776 #ifdef UF_HIDDEN
4777     { UF_HIDDEN, EXT_HIDDEN },
4778 #endif
4779
4780     /* Do not remove. We need to guarantee that this array has at least one
4781      * entry to build on HP-UX.
4782      */
4783     { 0, 0 }
4784
4785 };
4786
4787 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf,
4788                                 uint32_t *smb_fflags, uint32_t *smb_fmask)
4789 {
4790         int i;
4791
4792         for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
4793             *smb_fmask |= info2_flags_map[i].smb_fflag;
4794             if (psbuf->st_ex_flags & info2_flags_map[i].stat_fflag) {
4795                     *smb_fflags |= info2_flags_map[i].smb_fflag;
4796             }
4797         }
4798 }
4799
4800 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
4801                                 const uint32_t smb_fflags,
4802                                 const uint32_t smb_fmask,
4803                                 int *stat_fflags)
4804 {
4805         uint32_t max_fmask = 0;
4806         int i;
4807
4808         *stat_fflags = psbuf->st_ex_flags;
4809
4810         /* For each flags requested in smb_fmask, check the state of the
4811          * corresponding flag in smb_fflags and set or clear the matching
4812          * stat flag.
4813          */
4814
4815         for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
4816             max_fmask |= info2_flags_map[i].smb_fflag;
4817             if (smb_fmask & info2_flags_map[i].smb_fflag) {
4818                     if (smb_fflags & info2_flags_map[i].smb_fflag) {
4819                             *stat_fflags |= info2_flags_map[i].stat_fflag;
4820                     } else {
4821                             *stat_fflags &= ~info2_flags_map[i].stat_fflag;
4822                     }
4823             }
4824         }
4825
4826         /* If smb_fmask is asking to set any bits that are not supported by
4827          * our flag mappings, we should fail.
4828          */
4829         if ((smb_fmask & max_fmask) != smb_fmask) {
4830                 return False;
4831         }
4832
4833         return True;
4834 }
4835
4836
4837 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
4838  * of file flags and birth (create) time.
4839  */
4840 static char *store_file_unix_basic_info2(connection_struct *conn,
4841                                 char *pdata,
4842                                 files_struct *fsp,
4843                                 const SMB_STRUCT_STAT *psbuf)
4844 {
4845         uint32_t file_flags = 0;
4846         uint32_t flags_mask = 0;
4847
4848         pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
4849
4850         /* Create (birth) time 64 bit */
4851         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER,pdata, &psbuf->st_ex_btime);
4852         pdata += 8;
4853
4854         map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
4855         SIVAL(pdata, 0, file_flags); /* flags */
4856         SIVAL(pdata, 4, flags_mask); /* mask */
4857         pdata += 8;
4858
4859         return pdata;
4860 }
4861
4862 static NTSTATUS marshall_stream_info(unsigned int num_streams,
4863                                      const struct stream_struct *streams,
4864                                      char *data,
4865                                      unsigned int max_data_bytes,
4866                                      unsigned int *data_size)
4867 {
4868         unsigned int i;
4869         unsigned int ofs = 0;
4870
4871         if (max_data_bytes < 32) {
4872                 return NT_STATUS_INFO_LENGTH_MISMATCH;
4873         }
4874
4875         for (i = 0; i < num_streams; i++) {
4876                 unsigned int next_offset;
4877                 size_t namelen;
4878                 smb_ucs2_t *namebuf;
4879
4880                 if (!push_ucs2_talloc(talloc_tos(), &namebuf,
4881                                       streams[i].name, &namelen) ||
4882                     namelen <= 2)
4883                 {
4884                         return NT_STATUS_INVALID_PARAMETER;
4885                 }
4886
4887                 /*
4888                  * name_buf is now null-terminated, we need to marshall as not
4889                  * terminated
4890                  */
4891
4892                 namelen -= 2;
4893
4894                 /*
4895                  * We cannot overflow ...
4896                  */
4897                 if ((ofs + 24 + namelen) > max_data_bytes) {
4898                         DEBUG(10, ("refusing to overflow reply at stream %u\n",
4899                                 i));
4900                         TALLOC_FREE(namebuf);
4901                         return STATUS_BUFFER_OVERFLOW;
4902                 }
4903
4904                 SIVAL(data, ofs+4, namelen);
4905                 SOFF_T(data, ofs+8, streams[i].size);
4906                 SOFF_T(data, ofs+16, streams[i].alloc_size);
4907                 memcpy(data+ofs+24, namebuf, namelen);
4908                 TALLOC_FREE(namebuf);
4909
4910                 next_offset = ofs + 24 + namelen;
4911
4912                 if (i == num_streams-1) {
4913                         SIVAL(data, ofs, 0);
4914                 }
4915                 else {
4916                         unsigned int align = ndr_align_size(next_offset, 8);
4917
4918                         if ((next_offset + align) > max_data_bytes) {
4919                                 DEBUG(10, ("refusing to overflow align "
4920                                         "reply at stream %u\n",
4921                                         i));
4922                                 TALLOC_FREE(namebuf);
4923                                 return STATUS_BUFFER_OVERFLOW;
4924                         }
4925
4926                         memset(data+next_offset, 0, align);
4927                         next_offset += align;
4928
4929                         SIVAL(data, ofs, next_offset - ofs);
4930                         ofs = next_offset;
4931                 }
4932
4933                 ofs = next_offset;
4934         }
4935
4936         DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes, ofs));
4937
4938         *data_size = ofs;
4939
4940         return NT_STATUS_OK;
4941 }
4942
4943 #if defined(HAVE_POSIX_ACLS)
4944 static NTSTATUS smb_query_posix_acl(connection_struct *conn,
4945                                 struct smb_request *req,
4946                                 files_struct *fsp,
4947                                 struct smb_filename *smb_fname,
4948                                 char *pdata,
4949                                 unsigned int data_size_in,
4950                                 unsigned int *pdata_size_out)
4951 {
4952         SMB_ACL_T file_acl = NULL;
4953         SMB_ACL_T def_acl = NULL;
4954         uint16_t num_file_acls = 0;
4955         uint16_t num_def_acls = 0;
4956         unsigned int size_needed = 0;
4957         NTSTATUS status;
4958         bool ok;
4959         bool close_fsp = false;
4960
4961         /*
4962          * Ensure we always operate on a file descriptor, not just
4963          * the filename.
4964          */
4965         if (fsp == NULL) {
4966                 uint32_t access_mask = SEC_STD_READ_CONTROL|
4967                                         FILE_READ_ATTRIBUTES|
4968                                         FILE_WRITE_ATTRIBUTES;
4969
4970                 status = get_posix_fsp(conn,
4971                                         req,
4972                                         smb_fname,
4973                                         access_mask,
4974                                         &fsp);
4975
4976                 if (!NT_STATUS_IS_OK(status)) {
4977                         goto out;
4978                 }
4979                 close_fsp = true;
4980         }
4981
4982         SMB_ASSERT(fsp != NULL);
4983
4984         status = refuse_symlink(conn,
4985                                 fsp,
4986                                 fsp->fsp_name);
4987         if (!NT_STATUS_IS_OK(status)) {
4988                 goto out;
4989         }
4990
4991         file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp,
4992                                         talloc_tos());
4993
4994         if (file_acl == NULL && no_acl_syscall_error(errno)) {
4995                 DBG_INFO("ACLs not implemented on "
4996                         "filesystem containing %s\n",
4997                         fsp_str_dbg(fsp));
4998                 status = NT_STATUS_NOT_IMPLEMENTED;
4999                 goto out;
5000         }
5001
5002         if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
5003                 /*
5004                  * We can only have default POSIX ACLs on
5005                  * directories.
5006                  */
5007                 if (!fsp->fsp_flags.is_directory) {
5008                         DBG_INFO("Non-directory open %s\n",
5009                                 fsp_str_dbg(fsp));
5010                         status = NT_STATUS_INVALID_HANDLE;
5011                         goto out;
5012                 }
5013                 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn,
5014                                         fsp->fsp_name,
5015                                         SMB_ACL_TYPE_DEFAULT,
5016                                         talloc_tos());
5017                 def_acl = free_empty_sys_acl(conn, def_acl);
5018         }
5019
5020         num_file_acls = count_acl_entries(conn, file_acl);
5021         num_def_acls = count_acl_entries(conn, def_acl);
5022
5023         /* Wrap checks. */
5024         if (num_file_acls + num_def_acls < num_file_acls) {
5025                 status = NT_STATUS_INVALID_PARAMETER;
5026                 goto out;
5027         }
5028
5029         size_needed = num_file_acls + num_def_acls;
5030
5031         /*
5032          * (size_needed * SMB_POSIX_ACL_ENTRY_SIZE) must be less
5033          * than UINT_MAX, so check by division.
5034          */
5035         if (size_needed > (UINT_MAX/SMB_POSIX_ACL_ENTRY_SIZE)) {
5036                 status = NT_STATUS_INVALID_PARAMETER;
5037                 goto out;
5038         }
5039
5040         size_needed = size_needed*SMB_POSIX_ACL_ENTRY_SIZE;
5041         if (size_needed + SMB_POSIX_ACL_HEADER_SIZE < size_needed) {
5042                 status = NT_STATUS_INVALID_PARAMETER;
5043                 goto out;
5044         }
5045         size_needed += SMB_POSIX_ACL_HEADER_SIZE;
5046
5047         if ( data_size_in < size_needed) {
5048                 DBG_INFO("data_size too small (%u) need %u\n",
5049                         data_size_in,
5050                         size_needed);
5051                 status = NT_STATUS_BUFFER_TOO_SMALL;
5052                 goto out;
5053         }
5054
5055         SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
5056         SSVAL(pdata,2,num_file_acls);
5057         SSVAL(pdata,4,num_def_acls);
5058         pdata += SMB_POSIX_ACL_HEADER_SIZE;
5059
5060         ok = marshall_posix_acl(conn,
5061                         pdata,
5062                         &fsp->fsp_name->st,
5063                         file_acl);
5064         if (!ok) {
5065                 status = NT_STATUS_INTERNAL_ERROR;
5066                 goto out;
5067         }
5068         pdata += (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE);
5069
5070         ok = marshall_posix_acl(conn,
5071                         pdata,
5072                         &fsp->fsp_name->st,
5073                         def_acl);
5074         if (!ok) {
5075                 status = NT_STATUS_INTERNAL_ERROR;
5076                 goto out;
5077         }
5078
5079         *pdata_size_out = size_needed;
5080         status = NT_STATUS_OK;
5081
5082   out:
5083
5084         if (close_fsp) {
5085                 /*
5086                  * Ensure the stat struct in smb_fname is up to
5087                  * date. Structure copy.
5088                  */
5089                 smb_fname->st = fsp->fsp_name->st;
5090                 (void)close_file(req, fsp, NORMAL_CLOSE);
5091                 fsp = NULL;
5092         }
5093
5094         TALLOC_FREE(file_acl);
5095         TALLOC_FREE(def_acl);
5096         return status;
5097 }
5098 #endif
5099
5100 /****************************************************************************
5101  Reply to a TRANSACT2_QFILEINFO on a PIPE !
5102 ****************************************************************************/
5103
5104 static void call_trans2qpipeinfo(connection_struct *conn,
5105                                  struct smb_request *req,
5106                                  unsigned int tran_call,
5107                                  char **pparams, int total_params,
5108                                  char **ppdata, int total_data,
5109                                  unsigned int max_data_bytes)
5110 {
5111         char *params = *pparams;
5112         char *pdata = *ppdata;
5113         unsigned int data_size = 0;
5114         unsigned int param_size = 2;
5115         uint16_t info_level;
5116         files_struct *fsp;
5117
5118         if (!params) {
5119                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5120                 return;
5121         }
5122
5123         if (total_params < 4) {
5124                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5125                 return;
5126         }
5127
5128         fsp = file_fsp(req, SVAL(params,0));
5129         if (!fsp_is_np(fsp)) {
5130                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
5131                 return;
5132         }
5133
5134         info_level = SVAL(params,2);
5135
5136         *pparams = (char *)SMB_REALLOC(*pparams,2);
5137         if (*pparams == NULL) {
5138                 reply_nterror(req, NT_STATUS_NO_MEMORY);
5139                 return;
5140         }
5141         params = *pparams;
5142         SSVAL(params,0,0);
5143         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
5144                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5145                 return;
5146         }
5147         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
5148         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 
5149         if (*ppdata == NULL ) {
5150                 reply_nterror(req, NT_STATUS_NO_MEMORY);
5151                 return;
5152         }
5153         pdata = *ppdata;
5154
5155         switch (info_level) {
5156                 case SMB_FILE_STANDARD_INFORMATION:
5157                         memset(pdata,0,24);
5158                         SOFF_T(pdata,0,4096LL);
5159                         SIVAL(pdata,16,1);
5160                         SIVAL(pdata,20,1);
5161                         data_size = 24;
5162                         break;
5163
5164                 default:
5165                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5166                         return;
5167         }
5168
5169         send_trans2_replies(conn, req, NT_STATUS_OK, params, param_size, *ppdata, data_size,
5170                             max_data_bytes);
5171
5172         return;
5173 }
5174
5175 NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
5176                                TALLOC_CTX *mem_ctx,
5177                                struct smb_request *req,
5178                                uint16_t info_level,
5179                                files_struct *fsp,
5180                                struct smb_filename *smb_fname,
5181                                bool delete_pending,
5182                                struct timespec write_time_ts,
5183                                struct ea_list *ea_list,
5184                                int lock_data_count,
5185                                char *lock_data,
5186                                uint16_t flags2,
5187                                unsigned int max_data_bytes,
5188                                size_t *fixed_portion,
5189                                char **ppdata,
5190                                unsigned int *pdata_size)
5191 {
5192         char *pdata = *ppdata;
5193         char *dstart, *dend;
5194         unsigned int data_size;
5195         struct timespec create_time_ts, mtime_ts, atime_ts, ctime_ts;
5196         time_t create_time, mtime, atime, c_time;
5197         SMB_STRUCT_STAT *psbuf = &smb_fname->st;
5198         char *p;
5199         char *base_name;
5200         char *dos_fname;
5201         int mode;
5202         int nlink;
5203         NTSTATUS status;
5204         uint64_t file_size = 0;
5205         uint64_t pos = 0;
5206         uint64_t allocation_size = 0;
5207         uint64_t file_id = 0;
5208         uint32_t access_mask = 0;
5209         size_t len = 0;
5210
5211         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
5212                 return NT_STATUS_INVALID_LEVEL;
5213         }
5214
5215         DEBUG(5,("smbd_do_qfilepathinfo: %s (%s) level=%d max_data=%u\n",
5216                  smb_fname_str_dbg(smb_fname),
5217                  fsp_fnum_dbg(fsp),
5218                  info_level, max_data_bytes));
5219
5220         mode = dos_mode(conn, smb_fname);
5221         nlink = psbuf->st_ex_nlink;
5222
5223         if (nlink && (mode&FILE_ATTRIBUTE_DIRECTORY)) {
5224                 nlink = 1;
5225         }
5226
5227         if ((nlink > 0) && delete_pending) {
5228                 nlink -= 1;
5229         }
5230
5231         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
5232                 return NT_STATUS_INVALID_PARAMETER;
5233         }
5234
5235         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
5236         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 
5237         if (*ppdata == NULL) {
5238                 return NT_STATUS_NO_MEMORY;
5239         }
5240         pdata = *ppdata;
5241         dstart = pdata;
5242         dend = dstart + data_size - 1;
5243
5244         if (!is_omit_timespec(&write_time_ts) &&
5245             !INFO_LEVEL_IS_UNIX(info_level))
5246         {
5247                 update_stat_ex_mtime(psbuf, write_time_ts);
5248         }
5249
5250         create_time_ts = get_create_timespec(conn, fsp, smb_fname);
5251         mtime_ts = psbuf->st_ex_mtime;
5252         atime_ts = psbuf->st_ex_atime;
5253         ctime_ts = get_change_timespec(conn, fsp, smb_fname);
5254
5255         if (lp_dos_filetime_resolution(SNUM(conn))) {
5256                 dos_filetime_timespec(&create_time_ts);
5257                 dos_filetime_timespec(&mtime_ts);
5258                 dos_filetime_timespec(&atime_ts);
5259                 dos_filetime_timespec(&ctime_ts);
5260         }
5261
5262         create_time = convert_timespec_to_time_t(create_time_ts);
5263         mtime = convert_timespec_to_time_t(mtime_ts);
5264         atime = convert_timespec_to_time_t(atime_ts);
5265         c_time = convert_timespec_to_time_t(ctime_ts);
5266
5267         p = strrchr_m(smb_fname->base_name,'/');
5268         if (!p)
5269                 base_name = smb_fname->base_name;
5270         else
5271                 base_name = p+1;
5272
5273         /* NT expects the name to be in an exact form of the *full*
5274            filename. See the trans2 torture test */
5275         if (ISDOT(base_name)) {
5276                 dos_fname = talloc_strdup(mem_ctx, "\\");
5277                 if (!dos_fname) {
5278                         return NT_STATUS_NO_MEMORY;
5279                 }
5280         } else {
5281                 dos_fname = talloc_asprintf(mem_ctx,
5282                                 "\\%s",
5283                                 smb_fname->base_name);
5284                 if (!dos_fname) {
5285                         return NT_STATUS_NO_MEMORY;
5286                 }
5287                 if (is_ntfs_stream_smb_fname(smb_fname)) {
5288                         dos_fname = talloc_asprintf(dos_fname, "%s",
5289                                                     smb_fname->stream_name);
5290                         if (!dos_fname) {
5291                                 return NT_STATUS_NO_MEMORY;
5292                         }
5293                 }
5294
5295                 string_replace(dos_fname, '/', '\\');
5296         }
5297
5298         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, psbuf);
5299
5300         if (!fsp) {
5301                 /* Do we have this path open ? */
5302                 files_struct *fsp1;
5303                 struct file_id fileid = vfs_file_id_from_sbuf(conn, psbuf);
5304                 fsp1 = file_find_di_first(conn->sconn, fileid);
5305                 if (fsp1 && fsp1->initial_allocation_size) {
5306                         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, psbuf);
5307                 }
5308         }
5309
5310         if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
5311                 file_size = get_file_size_stat(psbuf);
5312         }
5313
5314         if (fsp) {
5315                 pos = fh_get_position_information(fsp->fh);
5316         }
5317
5318         if (fsp) {
5319                 access_mask = fsp->access_mask;
5320         } else {
5321                 /* GENERIC_EXECUTE mapping from Windows */
5322                 access_mask = 0x12019F;
5323         }
5324
5325         /* This should be an index number - looks like
5326            dev/ino to me :-)
5327
5328            I think this causes us to fail the IFSKIT
5329            BasicFileInformationTest. -tpot */
5330         file_id = SMB_VFS_FS_FILE_ID(conn, psbuf);
5331
5332         *fixed_portion = 0;
5333
5334         switch (info_level) {
5335                 case SMB_INFO_STANDARD:
5336                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
5337                         data_size = 22;
5338                         srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
5339                         srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
5340                         srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
5341                         SIVAL(pdata,l1_cbFile,(uint32_t)file_size);
5342                         SIVAL(pdata,l1_cbFileAlloc,(uint32_t)allocation_size);
5343                         SSVAL(pdata,l1_attrFile,mode);
5344                         break;
5345
5346                 case SMB_INFO_QUERY_EA_SIZE:
5347                 {
5348                         unsigned int ea_size =
5349                             estimate_ea_size(conn, fsp,
5350                                              smb_fname);
5351                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
5352                         data_size = 26;
5353                         srv_put_dos_date2(pdata,0,create_time);
5354                         srv_put_dos_date2(pdata,4,atime);
5355                         srv_put_dos_date2(pdata,8,mtime); /* write time */
5356                         SIVAL(pdata,12,(uint32_t)file_size);
5357                         SIVAL(pdata,16,(uint32_t)allocation_size);
5358                         SSVAL(pdata,20,mode);
5359                         SIVAL(pdata,22,ea_size);
5360                         break;
5361                 }
5362
5363                 case SMB_INFO_IS_NAME_VALID:
5364                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
5365                         if (fsp) {
5366                                 /* os/2 needs this ? really ?*/
5367                                 return NT_STATUS_DOS(ERRDOS, ERRbadfunc);
5368                         }
5369                         /* This is only reached for qpathinfo */
5370                         data_size = 0;
5371                         break;
5372
5373                 case SMB_INFO_QUERY_EAS_FROM_LIST:
5374                 {
5375                         size_t total_ea_len = 0;
5376                         struct ea_list *ea_file_list = NULL;
5377                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
5378
5379                         status =
5380                             get_ea_list_from_file(mem_ctx, conn, fsp,
5381                                                   smb_fname,
5382                                                   &total_ea_len, &ea_file_list);
5383                         if (!NT_STATUS_IS_OK(status)) {
5384                                 return status;
5385                         }
5386
5387                         ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
5388
5389                         if (!ea_list || (total_ea_len > data_size)) {
5390                                 data_size = 4;
5391                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
5392                                 break;
5393                         }
5394
5395                         data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
5396                         break;
5397                 }
5398
5399                 case SMB_INFO_QUERY_ALL_EAS:
5400                 {
5401                         /* We have data_size bytes to put EA's into. */
5402                         size_t total_ea_len = 0;
5403                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
5404
5405                         status = get_ea_list_from_file(mem_ctx, conn, fsp,
5406                                                         smb_fname,
5407                                                         &total_ea_len, &ea_list);
5408                         if (!NT_STATUS_IS_OK(status)) {
5409                                 return status;
5410                         }
5411
5412                         if (!ea_list || (total_ea_len > data_size)) {
5413                                 data_size = 4;
5414                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
5415                                 break;
5416                         }
5417
5418                         data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
5419                         break;
5420                 }
5421
5422                 case SMB2_FILE_FULL_EA_INFORMATION:
5423                 {
5424                         /* We have data_size bytes to put EA's into. */
5425                         size_t total_ea_len = 0;
5426                         struct ea_list *ea_file_list = NULL;
5427
5428                         DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
5429
5430                         /*TODO: add filtering and index handling */
5431
5432                         status  =
5433                                 get_ea_list_from_file(mem_ctx, conn, fsp,
5434                                                   smb_fname,
5435                                                   &total_ea_len, &ea_file_list);
5436                         if (!NT_STATUS_IS_OK(status)) {
5437                                 return status;
5438                         }
5439                         if (!ea_file_list) {
5440                                 return NT_STATUS_NO_EAS_ON_FILE;
5441                         }
5442
5443                         status = fill_ea_chained_buffer(mem_ctx,
5444                                                         pdata,
5445                                                         data_size,
5446                                                         &data_size,
5447                                                         conn, ea_file_list);
5448                         if (!NT_STATUS_IS_OK(status)) {
5449                                 return status;
5450                         }
5451                         break;
5452                 }
5453
5454                 case SMB_FILE_BASIC_INFORMATION:
5455                 case SMB_QUERY_FILE_BASIC_INFO:
5456
5457                         if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
5458                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
5459                                 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
5460                         } else {
5461                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
5462                                 data_size = 40;
5463                                 SIVAL(pdata,36,0);
5464                         }
5465                         put_long_date_full_timespec(conn->ts_res,pdata,&create_time_ts);
5466                         put_long_date_full_timespec(conn->ts_res,pdata+8,&atime_ts);
5467                         put_long_date_full_timespec(conn->ts_res,pdata+16,&mtime_ts); /* write time */
5468                         put_long_date_full_timespec(conn->ts_res,pdata+24,&ctime_ts); /* change time */
5469                         SIVAL(pdata,32,mode);
5470
5471                         DEBUG(5,("SMB_QFBI - "));
5472                         DEBUG(5,("create: %s ", ctime(&create_time)));
5473                         DEBUG(5,("access: %s ", ctime(&atime)));
5474                         DEBUG(5,("write: %s ", ctime(&mtime)));
5475                         DEBUG(5,("change: %s ", ctime(&c_time)));
5476                         DEBUG(5,("mode: %x\n", mode));
5477                         *fixed_portion = data_size;
5478                         break;
5479
5480                 case SMB_FILE_STANDARD_INFORMATION:
5481                 case SMB_QUERY_FILE_STANDARD_INFO:
5482
5483                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
5484                         data_size = 24;
5485                         SOFF_T(pdata,0,allocation_size);
5486                         SOFF_T(pdata,8,file_size);
5487                         SIVAL(pdata,16,nlink);
5488                         SCVAL(pdata,20,delete_pending?1:0);
5489                         SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
5490                         SSVAL(pdata,22,0); /* Padding. */
5491                         *fixed_portion = 24;
5492                         break;
5493
5494                 case SMB_FILE_EA_INFORMATION:
5495                 case SMB_QUERY_FILE_EA_INFO:
5496                 {
5497                         unsigned int ea_size =
5498                             estimate_ea_size(conn, fsp, smb_fname);
5499                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
5500                         data_size = 4;
5501                         *fixed_portion = 4;
5502                         SIVAL(pdata,0,ea_size);
5503                         break;
5504                 }
5505
5506                 /* Get the 8.3 name - used if NT SMB was negotiated. */
5507                 case SMB_QUERY_FILE_ALT_NAME_INFO:
5508                 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
5509                 {
5510                         char mangled_name[13];
5511                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
5512                         if (!name_to_8_3(base_name,mangled_name,
5513                                                 True,conn->params)) {
5514                                 return NT_STATUS_NO_MEMORY;
5515                         }
5516                         status = srvstr_push(dstart, flags2,
5517                                           pdata+4, mangled_name,
5518                                           PTR_DIFF(dend, pdata+4),
5519                                           STR_UNICODE, &len);
5520                         if (!NT_STATUS_IS_OK(status)) {
5521                                 return status;
5522                         }
5523                         data_size = 4 + len;
5524                         SIVAL(pdata,0,len);
5525                         *fixed_portion = 8;
5526                         break;
5527                 }
5528
5529                 case SMB_QUERY_FILE_NAME_INFO:
5530                 {
5531                         /*
5532                           this must be *exactly* right for ACLs on mapped drives to work
5533                          */
5534                         status = srvstr_push(dstart, flags2,
5535                                           pdata+4, dos_fname,
5536                                           PTR_DIFF(dend, pdata+4),
5537                                           STR_UNICODE, &len);
5538                         if (!NT_STATUS_IS_OK(status)) {
5539                                 return status;
5540                         }
5541                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
5542                         data_size = 4 + len;
5543                         SIVAL(pdata,0,len);
5544                         break;
5545                 }
5546
5547                 case SMB_FILE_NORMALIZED_NAME_INFORMATION:
5548                 {
5549                         char *nfname = NULL;
5550
5551                         if (fsp == NULL || !fsp->conn->sconn->using_smb2) {
5552                                 return NT_STATUS_INVALID_LEVEL;
5553                         }
5554
5555                         nfname = talloc_strdup(mem_ctx, smb_fname->base_name);
5556                         if (nfname == NULL) {
5557                                 return NT_STATUS_NO_MEMORY;
5558                         }
5559
5560                         if (ISDOT(nfname)) {
5561                                 nfname[0] = '\0';
5562                         }
5563                         string_replace(nfname, '/', '\\');
5564
5565                         if (smb_fname->stream_name != NULL) {
5566                                 const char *s = smb_fname->stream_name;
5567                                 const char *e = NULL;
5568                                 size_t n;
5569
5570                                 SMB_ASSERT(s[0] != '\0');
5571
5572                                 /*
5573                                  * smb_fname->stream_name is in form
5574                                  * of ':StrEam:$DATA', but we should only
5575                                  * append ':StrEam' here.
5576                                  */
5577
5578                                 e = strchr(&s[1], ':');
5579                                 if (e == NULL) {
5580                                         n = strlen(s);
5581                                 } else {
5582                                         n = PTR_DIFF(e, s);
5583                                 }
5584                                 nfname = talloc_strndup_append(nfname, s, n);
5585                                 if (nfname == NULL) {
5586                                         return NT_STATUS_NO_MEMORY;
5587                                 }
5588                         }
5589
5590                         status = srvstr_push(dstart, flags2,
5591                                           pdata+4, nfname,
5592                                           PTR_DIFF(dend, pdata+4),
5593                                           STR_UNICODE, &len);
5594                         if (!NT_STATUS_IS_OK(status)) {
5595                                 return status;
5596                         }
5597                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NORMALIZED_NAME_INFORMATION\n"));
5598                         data_size = 4 + len;
5599                         SIVAL(pdata,0,len);
5600                         *fixed_portion = 8;
5601                         break;
5602                 }
5603
5604                 case SMB_FILE_ALLOCATION_INFORMATION:
5605                 case SMB_QUERY_FILE_ALLOCATION_INFO:
5606                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
5607                         data_size = 8;
5608                         SOFF_T(pdata,0,allocation_size);
5609                         break;
5610
5611                 case SMB_FILE_END_OF_FILE_INFORMATION:
5612                 case SMB_QUERY_FILE_END_OF_FILEINFO:
5613                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
5614                         data_size = 8;
5615                         SOFF_T(pdata,0,file_size);
5616                         break;
5617
5618                 case SMB_QUERY_FILE_ALL_INFO:
5619                 case SMB_FILE_ALL_INFORMATION:
5620                 {
5621                         unsigned int ea_size =
5622                             estimate_ea_size(conn, fsp, smb_fname);
5623                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
5624                         put_long_date_full_timespec(conn->ts_res,pdata,&create_time_ts);
5625                         put_long_date_full_timespec(conn->ts_res,pdata+8,&atime_ts);
5626                         put_long_date_full_timespec(conn->ts_res,pdata+16,&mtime_ts); /* write time */
5627                         put_long_date_full_timespec(conn->ts_res,pdata+24,&ctime_ts); /* change time */
5628                         SIVAL(pdata,32,mode);
5629                         SIVAL(pdata,36,0); /* padding. */
5630                         pdata += 40;
5631                         SOFF_T(pdata,0,allocation_size);
5632                         SOFF_T(pdata,8,file_size);
5633                         SIVAL(pdata,16,nlink);
5634                         SCVAL(pdata,20,delete_pending);
5635                         SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
5636                         SSVAL(pdata,22,0);
5637                         pdata += 24;
5638                         SIVAL(pdata,0,ea_size);
5639                         pdata += 4; /* EA info */
5640                         status = srvstr_push(dstart, flags2,
5641                                           pdata+4, dos_fname,
5642                                           PTR_DIFF(dend, pdata+4),
5643                                           STR_UNICODE, &len);
5644                         if (!NT_STATUS_IS_OK(status)) {
5645                                 return status;
5646                         }
5647                         SIVAL(pdata,0,len);
5648                         pdata += 4 + len;
5649                         data_size = PTR_DIFF(pdata,(*ppdata));
5650                         *fixed_portion = 10;
5651                         break;
5652                 }
5653
5654                 case SMB2_FILE_ALL_INFORMATION:
5655                 {
5656                         unsigned int ea_size =
5657                             estimate_ea_size(conn, fsp, smb_fname);
5658                         DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
5659                         put_long_date_full_timespec(conn->ts_res,pdata+0x00,&create_time_ts);
5660                         put_long_date_full_timespec(conn->ts_res,pdata+0x08,&atime_ts);
5661                         put_long_date_full_timespec(conn->ts_res,pdata+0x10,&mtime_ts); /* write time */
5662                         put_long_date_full_timespec(conn->ts_res,pdata+0x18,&ctime_ts); /* change time */
5663                         SIVAL(pdata,    0x20, mode);
5664                         SIVAL(pdata,    0x24, 0); /* padding. */
5665                         SBVAL(pdata,    0x28, allocation_size);
5666                         SBVAL(pdata,    0x30, file_size);
5667                         SIVAL(pdata,    0x38, nlink);
5668                         SCVAL(pdata,    0x3C, delete_pending);
5669                         SCVAL(pdata,    0x3D, (mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
5670                         SSVAL(pdata,    0x3E, 0); /* padding */
5671                         SBVAL(pdata,    0x40, file_id);
5672                         SIVAL(pdata,    0x48, ea_size);
5673                         SIVAL(pdata,    0x4C, access_mask);
5674                         SBVAL(pdata,    0x50, pos);
5675                         SIVAL(pdata,    0x58, mode); /*TODO: mode != mode fix this!!! */
5676                         SIVAL(pdata,    0x5C, 0); /* No alignment needed. */
5677
5678                         pdata += 0x60;
5679
5680                         status = srvstr_push(dstart, flags2,
5681                                           pdata+4, dos_fname,
5682                                           PTR_DIFF(dend, pdata+4),
5683                                           STR_UNICODE, &len);
5684                         if (!NT_STATUS_IS_OK(status)) {
5685                                 return status;
5686                         }
5687                         SIVAL(pdata,0,len);
5688                         pdata += 4 + len;
5689                         data_size = PTR_DIFF(pdata,(*ppdata));
5690                         *fixed_portion = 104;
5691                         break;
5692                 }
5693                 case SMB_FILE_INTERNAL_INFORMATION:
5694
5695                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
5696                         SBVAL(pdata, 0, file_id);
5697                         data_size = 8;
5698                         *fixed_portion = 8;
5699                         break;
5700
5701                 case SMB_FILE_ACCESS_INFORMATION:
5702                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
5703                         SIVAL(pdata, 0, access_mask);
5704                         data_size = 4;
5705                         *fixed_portion = 4;
5706                         break;
5707
5708                 case SMB_FILE_NAME_INFORMATION:
5709                         /* Pathname with leading '\'. */
5710                         {
5711                                 size_t byte_len;
5712                                 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
5713                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
5714                                 SIVAL(pdata,0,byte_len);
5715                                 data_size = 4 + byte_len;
5716                                 break;
5717                         }
5718
5719                 case SMB_FILE_DISPOSITION_INFORMATION:
5720                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
5721                         data_size = 1;
5722                         SCVAL(pdata,0,delete_pending);
5723                         *fixed_portion = 1;
5724                         break;
5725
5726                 case SMB_FILE_POSITION_INFORMATION:
5727                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
5728                         data_size = 8;
5729                         SOFF_T(pdata,0,pos);
5730                         *fixed_portion = 8;
5731                         break;
5732
5733                 case SMB_FILE_MODE_INFORMATION:
5734                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
5735                         SIVAL(pdata,0,mode);
5736                         data_size = 4;
5737                         *fixed_portion = 4;
5738                         break;
5739
5740                 case SMB_FILE_ALIGNMENT_INFORMATION:
5741                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
5742                         SIVAL(pdata,0,0); /* No alignment needed. */
5743                         data_size = 4;
5744                         *fixed_portion = 4;
5745                         break;
5746
5747                 /*
5748                  * NT4 server just returns "invalid query" to this - if we try
5749                  * to answer it then NTws gets a BSOD! (tridge).  W2K seems to
5750                  * want this. JRA.
5751                  */
5752                 /* The first statement above is false - verified using Thursby
5753                  * client against NT4 -- gcolley.
5754                  */
5755                 case SMB_QUERY_FILE_STREAM_INFO:
5756                 case SMB_FILE_STREAM_INFORMATION: {
5757                         unsigned int num_streams = 0;
5758                         struct stream_struct *streams = NULL;
5759
5760                         DEBUG(10,("smbd_do_qfilepathinfo: "
5761                                   "SMB_FILE_STREAM_INFORMATION\n"));
5762
5763                         if (is_ntfs_stream_smb_fname(smb_fname)) {
5764                                 return NT_STATUS_INVALID_PARAMETER;
5765                         }
5766
5767                         status = vfs_streaminfo(conn,
5768                                                 fsp,
5769                                                 smb_fname,
5770                                                 talloc_tos(),
5771                                                 &num_streams,
5772                                                 &streams);
5773
5774                         if (!NT_STATUS_IS_OK(status)) {
5775                                 DEBUG(10, ("could not get stream info: %s\n",
5776                                            nt_errstr(status)));
5777                                 return status;
5778                         }
5779
5780                         status = marshall_stream_info(num_streams, streams,
5781                                                       pdata, max_data_bytes,
5782                                                       &data_size);
5783
5784                         if (!NT_STATUS_IS_OK(status)) {
5785                                 DEBUG(10, ("marshall_stream_info failed: %s\n",
5786                                            nt_errstr(status)));
5787                                 TALLOC_FREE(streams);
5788                                 return status;
5789                         }
5790
5791                         TALLOC_FREE(streams);
5792
5793                         *fixed_portion = 32;
5794
5795                         break;
5796                 }
5797                 case SMB_QUERY_COMPRESSION_INFO:
5798                 case SMB_FILE_COMPRESSION_INFORMATION:
5799                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
5800                         SOFF_T(pdata,0,file_size);
5801                         SIVAL(pdata,8,0); /* ??? */
5802                         SIVAL(pdata,12,0); /* ??? */
5803                         data_size = 16;
5804                         *fixed_portion = 16;
5805                         break;
5806
5807                 case SMB_FILE_NETWORK_OPEN_INFORMATION:
5808                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
5809                         put_long_date_full_timespec(conn->ts_res,pdata,&create_time_ts);
5810                         put_long_date_full_timespec(conn->ts_res,pdata+8,&atime_ts);
5811                         put_long_date_full_timespec(conn->ts_res,pdata+16,&mtime_ts); /* write time */
5812                         put_long_date_full_timespec(conn->ts_res,pdata+24,&ctime_ts); /* change time */
5813                         SOFF_T(pdata,32,allocation_size);
5814                         SOFF_T(pdata,40,file_size);
5815                         SIVAL(pdata,48,mode);
5816                         SIVAL(pdata,52,0); /* ??? */
5817                         data_size = 56;
5818                         *fixed_portion = 56;
5819                         break;
5820
5821                 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
5822                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
5823                         SIVAL(pdata,0,mode);
5824                         SIVAL(pdata,4,0);
5825                         data_size = 8;
5826                         *fixed_portion = 8;
5827                         break;
5828
5829                 /*
5830                  * CIFS UNIX Extensions.
5831                  */
5832
5833                 case SMB_QUERY_FILE_UNIX_BASIC:
5834
5835                         pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
5836                         data_size = PTR_DIFF(pdata,(*ppdata));
5837
5838                         DEBUG(4,("smbd_do_qfilepathinfo: "
5839                                  "SMB_QUERY_FILE_UNIX_BASIC\n"));
5840                         dump_data(4, (uint8_t *)(*ppdata), data_size);
5841
5842                         break;
5843
5844                 case SMB_QUERY_FILE_UNIX_INFO2:
5845
5846                         pdata = store_file_unix_basic_info2(conn, pdata, fsp, psbuf);
5847                         data_size = PTR_DIFF(pdata,(*ppdata));
5848
5849                         {
5850                                 int i;
5851                                 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
5852
5853                                 for (i=0; i<100; i++)
5854                                         DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
5855                                 DEBUG(4,("\n"));
5856                         }
5857
5858                         break;
5859
5860                 case SMB_QUERY_FILE_UNIX_LINK:
5861                         {
5862                                 int link_len = 0;
5863                                 char *buffer = talloc_array(mem_ctx, char, PATH_MAX+1);
5864
5865                                 if (!buffer) {
5866                                         return NT_STATUS_NO_MEMORY;
5867                                 }
5868
5869                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
5870 #ifdef S_ISLNK
5871                                 if(!S_ISLNK(psbuf->st_ex_mode)) {
5872                                         return NT_STATUS_DOS(ERRSRV, ERRbadlink);
5873                                 }
5874 #else
5875                                 return NT_STATUS_DOS(ERRDOS, ERRbadlink);
5876 #endif
5877                                 link_len = SMB_VFS_READLINKAT(conn,
5878                                                         conn->cwd_fsp,
5879                                                         smb_fname,
5880                                                         buffer,
5881                                                         PATH_MAX);
5882
5883                                 if (link_len == -1) {
5884                                         return map_nt_error_from_unix(errno);
5885                                 }
5886                                 buffer[link_len] = 0;
5887                                 status = srvstr_push(dstart, flags2,
5888                                                   pdata, buffer,
5889                                                   PTR_DIFF(dend, pdata),
5890                                                   STR_TERMINATE, &len);
5891                                 if (!NT_STATUS_IS_OK(status)) {
5892                                         return status;
5893                                 }
5894                                 pdata += len;
5895                                 data_size = PTR_DIFF(pdata,(*ppdata));
5896
5897                                 break;
5898                         }
5899
5900 #if defined(HAVE_POSIX_ACLS)
5901                 case SMB_QUERY_POSIX_ACL:
5902                         {
5903                                 status = smb_query_posix_acl(conn,
5904                                                         req,
5905                                                         fsp,
5906                                                         smb_fname,
5907                                                         pdata,
5908                                                         data_size,
5909                                                         &data_size);
5910                                 if (!NT_STATUS_IS_OK(status)) {
5911                                         return status;
5912                                 }
5913                                 break;
5914                         }
5915 #endif
5916
5917
5918                 case SMB_QUERY_POSIX_LOCK:
5919                 {
5920                         uint64_t count;
5921                         uint64_t offset;
5922                         uint64_t smblctx;
5923                         enum brl_type lock_type;
5924
5925                         /* We need an open file with a real fd for this. */
5926                         if (fsp == NULL ||
5927                             fsp->fsp_flags.is_pathref ||
5928                             fsp_get_io_fd(fsp) == -1)
5929                         {
5930                                 return NT_STATUS_INVALID_LEVEL;
5931                         }
5932
5933                         if (lock_data_count != POSIX_LOCK_DATA_SIZE) {
5934                                 return NT_STATUS_INVALID_PARAMETER;
5935                         }
5936
5937                         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
5938                                 case POSIX_LOCK_TYPE_READ:
5939                                         lock_type = READ_LOCK;
5940                                         break;
5941                                 case POSIX_LOCK_TYPE_WRITE:
5942                                         lock_type = WRITE_LOCK;
5943                                         break;
5944                                 case POSIX_LOCK_TYPE_UNLOCK:
5945                                 default:
5946                                         /* There's no point in asking for an unlock... */
5947                                         return NT_STATUS_INVALID_PARAMETER;
5948                         }
5949
5950                         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
5951                         offset = BVAL(pdata,POSIX_LOCK_START_OFFSET);
5952                         count = BVAL(pdata,POSIX_LOCK_LEN_OFFSET);
5953
5954                         status = query_lock(fsp,
5955                                         &smblctx,
5956                                         &count,
5957                                         &offset,
5958                                         &lock_type,
5959                                         POSIX_LOCK);
5960
5961                         if (ERROR_WAS_LOCK_DENIED(status)) {
5962                                 /* Here we need to report who has it locked... */
5963                                 data_size = POSIX_LOCK_DATA_SIZE;
5964
5965                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
5966                                 SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
5967                                 SIVAL(pdata, POSIX_LOCK_PID_OFFSET, (uint32_t)smblctx);
5968                                 SBVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
5969                                 SBVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
5970
5971                         } else if (NT_STATUS_IS_OK(status)) {
5972                                 /* For success we just return a copy of what we sent
5973                                    with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
5974                                 data_size = POSIX_LOCK_DATA_SIZE;
5975                                 memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
5976                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
5977                         } else {
5978                                 return status;
5979                         }
5980                         break;
5981                 }
5982
5983                 default:
5984                         return NT_STATUS_INVALID_LEVEL;
5985         }
5986
5987         *pdata_size = data_size;
5988         return NT_STATUS_OK;
5989 }
5990
5991 /****************************************************************************
5992  Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
5993  file name or file id).
5994 ****************************************************************************/
5995
5996 static void call_trans2qfilepathinfo(connection_struct *conn,
5997                                      struct smb_request *req,
5998                                      unsigned int tran_call,
5999                                      char **pparams, int total_params,
6000                                      char **ppdata, int total_data,
6001                                      unsigned int max_data_bytes)
6002 {
6003         char *params = *pparams;
6004         char *pdata = *ppdata;
6005         uint16_t info_level;
6006         unsigned int data_size = 0;
6007         unsigned int param_size = 2;
6008         struct smb_filename *smb_fname = NULL;
6009         bool delete_pending = False;
6010         struct timespec write_time_ts;
6011         files_struct *fsp = NULL;
6012         struct file_id fileid;
6013         struct ea_list *ea_list = NULL;
6014         int lock_data_count = 0;
6015         char *lock_data = NULL;
6016         size_t fixed_portion;
6017         NTSTATUS status = NT_STATUS_OK;
6018
6019         if (!params) {
6020                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6021                 return;
6022         }
6023
6024         ZERO_STRUCT(write_time_ts);
6025
6026         if (tran_call == TRANSACT2_QFILEINFO) {
6027                 if (total_params < 4) {
6028                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6029                         return;
6030                 }
6031
6032                 if (IS_IPC(conn)) {
6033                         call_trans2qpipeinfo(conn, req, tran_call,
6034                                              pparams, total_params,
6035                                              ppdata, total_data,
6036                                              max_data_bytes);
6037                         return;
6038                 }
6039
6040                 fsp = file_fsp(req, SVAL(params,0));
6041                 info_level = SVAL(params,2);
6042
6043                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
6044
6045                 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
6046                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
6047                         return;
6048                 }
6049
6050                 /* Initial check for valid fsp ptr. */
6051                 if (!check_fsp_open(conn, req, fsp)) {
6052                         return;
6053                 }
6054
6055                 smb_fname = fsp->fsp_name;
6056
6057                 if(fsp->fake_file_handle) {
6058                         /*
6059                          * This is actually for the QUOTA_FAKE_FILE --metze
6060                          */
6061
6062                         /* We know this name is ok, it's already passed the checks. */
6063
6064                 } else if(fsp_get_pathref_fd(fsp) == -1) {
6065                         /*
6066                          * This is actually a QFILEINFO on a directory
6067                          * handle (returned from an NT SMB). NT5.0 seems
6068                          * to do this call. JRA.
6069                          */
6070
6071                         if (INFO_LEVEL_IS_UNIX(info_level)) {
6072                                 /* Always do lstat for UNIX calls. */
6073                                 if (SMB_VFS_LSTAT(conn, smb_fname)) {
6074                                         DEBUG(3,("call_trans2qfilepathinfo: "
6075                                                  "SMB_VFS_LSTAT of %s failed "
6076                                                  "(%s)\n",
6077                                                  smb_fname_str_dbg(smb_fname),
6078                                                  strerror(errno)));
6079                                         reply_nterror(req,
6080                                                 map_nt_error_from_unix(errno));
6081                                         return;
6082                                 }
6083                         } else if (SMB_VFS_STAT(conn, smb_fname)) {
6084                                 DEBUG(3,("call_trans2qfilepathinfo: "
6085                                          "SMB_VFS_STAT of %s failed (%s)\n",
6086                                          smb_fname_str_dbg(smb_fname),
6087                                          strerror(errno)));
6088                                 reply_nterror(req,
6089                                         map_nt_error_from_unix(errno));
6090                                 return;
6091                         }
6092
6093                         if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
6094                                 fileid = vfs_file_id_from_sbuf(
6095                                         conn, &smb_fname->st);
6096                                 get_file_infos(fileid, fsp->name_hash,
6097                                                &delete_pending,
6098                                                &write_time_ts);
6099                         }
6100                 } else {
6101                         /*
6102                          * Original code - this is an open file.
6103                          */
6104                         if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
6105                                 DEBUG(3, ("fstat of %s failed (%s)\n",
6106                                           fsp_fnum_dbg(fsp), strerror(errno)));
6107                                 reply_nterror(req,
6108                                         map_nt_error_from_unix(errno));
6109                                 return;
6110                         }
6111                         if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
6112                                 fileid = vfs_file_id_from_sbuf(
6113                                         conn, &smb_fname->st);
6114                                 get_file_infos(fileid, fsp->name_hash,
6115                                                &delete_pending,
6116                                                &write_time_ts);
6117                         }
6118                 }
6119
6120         } else {
6121                 uint32_t name_hash;
6122                 char *fname = NULL;
6123                 uint32_t ucf_flags = ucf_flags_from_smb_request(req);
6124
6125                 /* qpathinfo */
6126                 if (total_params < 7) {
6127                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6128                         return;
6129                 }
6130
6131                 info_level = SVAL(params,0);
6132
6133                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
6134
6135                 if (INFO_LEVEL_IS_UNIX(info_level)) {
6136                         if (!lp_unix_extensions()) {
6137                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
6138                                 return;
6139                         }
6140                 }
6141
6142                 if (req->posix_pathnames) {
6143                         srvstr_get_path_posix(req,
6144                                 params,
6145                                 req->flags2,
6146                                 &fname,
6147                                 &params[6],
6148                                 total_params - 6,
6149                                 STR_TERMINATE,
6150                                 &status);
6151                 } else {
6152                         srvstr_get_path(req,
6153                                 params,
6154                                 req->flags2,
6155                                 &fname,
6156                                 &params[6],
6157                                 total_params - 6,
6158                                 STR_TERMINATE,
6159                                 &status);
6160                 }
6161                 if (!NT_STATUS_IS_OK(status)) {
6162                         reply_nterror(req, status);
6163                         return;
6164                 }
6165
6166                 status = filename_convert(req,
6167                                         conn,
6168                                         fname,
6169                                         ucf_flags,
6170                                         0,
6171                                         &smb_fname);
6172                 if (!NT_STATUS_IS_OK(status)) {
6173                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6174                                 reply_botherror(req,
6175                                                 NT_STATUS_PATH_NOT_COVERED,
6176                                                 ERRSRV, ERRbadpath);
6177                                 return;
6178                         }
6179                         reply_nterror(req, status);
6180                         return;
6181                 }
6182
6183                 /* If this is a stream, check if there is a delete_pending. */
6184                 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6185                     && is_ntfs_stream_smb_fname(smb_fname)) {
6186                         struct smb_filename *smb_fname_base;
6187
6188                         /* Create an smb_filename with stream_name == NULL. */
6189                         smb_fname_base = synthetic_smb_fname(
6190                                                 talloc_tos(),
6191                                                 smb_fname->base_name,
6192                                                 NULL,
6193                                                 NULL,
6194                                                 smb_fname->twrp,
6195                                                 smb_fname->flags);
6196                         if (smb_fname_base == NULL) {
6197                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
6198                                 return;
6199                         }
6200
6201                         if (INFO_LEVEL_IS_UNIX(info_level) || req->posix_pathnames) {
6202                                 /* Always do lstat for UNIX calls. */
6203                                 if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
6204                                         DEBUG(3,("call_trans2qfilepathinfo: "
6205                                                  "SMB_VFS_LSTAT of %s failed "
6206                                                  "(%s)\n",
6207                                                  smb_fname_str_dbg(smb_fname_base),
6208                                                  strerror(errno)));
6209                                         TALLOC_FREE(smb_fname_base);
6210                                         reply_nterror(req,
6211                                                 map_nt_error_from_unix(errno));
6212                                         return;
6213                                 }
6214                         } else {
6215                                 if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
6216                                         DEBUG(3,("call_trans2qfilepathinfo: "
6217                                                  "fileinfo of %s failed "
6218                                                  "(%s)\n",
6219                                                  smb_fname_str_dbg(smb_fname_base),
6220                                                  strerror(errno)));
6221                                         TALLOC_FREE(smb_fname_base);
6222                                         reply_nterror(req,
6223                                                 map_nt_error_from_unix(errno));
6224                                         return;
6225                                 }
6226                         }
6227
6228                         status = file_name_hash(conn,
6229                                         smb_fname_str_dbg(smb_fname_base),
6230                                         &name_hash);
6231                         if (!NT_STATUS_IS_OK(status)) {
6232                                 TALLOC_FREE(smb_fname_base);
6233                                 reply_nterror(req, status);
6234                                 return;
6235                         }
6236
6237                         fileid = vfs_file_id_from_sbuf(conn,
6238                                                        &smb_fname_base->st);
6239                         TALLOC_FREE(smb_fname_base);
6240                         get_file_infos(fileid, name_hash, &delete_pending, NULL);
6241                         if (delete_pending) {
6242                                 reply_nterror(req, NT_STATUS_DELETE_PENDING);
6243                                 return;
6244                         }
6245                 }
6246
6247                 if (INFO_LEVEL_IS_UNIX(info_level) || req->posix_pathnames) {
6248                         /* Always do lstat for UNIX calls. */
6249                         if (SMB_VFS_LSTAT(conn, smb_fname)) {
6250                                 DEBUG(3,("call_trans2qfilepathinfo: "
6251                                          "SMB_VFS_LSTAT of %s failed (%s)\n",
6252                                          smb_fname_str_dbg(smb_fname),
6253                                          strerror(errno)));
6254                                 reply_nterror(req,
6255                                         map_nt_error_from_unix(errno));
6256                                 return;
6257                         }
6258
6259                 } else {
6260                         if (SMB_VFS_STAT(conn, smb_fname) != 0) {
6261                                 DEBUG(3,("call_trans2qfilepathinfo: "
6262                                          "SMB_VFS_STAT of %s failed (%s)\n",
6263                                          smb_fname_str_dbg(smb_fname),
6264                                          strerror(errno)));
6265                                 reply_nterror(req,
6266                                         map_nt_error_from_unix(errno));
6267                                 return;
6268                         }
6269                 }
6270
6271                 status = file_name_hash(conn,
6272                                 smb_fname_str_dbg(smb_fname),
6273                                 &name_hash);
6274                 if (!NT_STATUS_IS_OK(status)) {
6275                         reply_nterror(req, status);
6276                         return;
6277                 }
6278
6279                 if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
6280                         fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
6281                         get_file_infos(fileid, name_hash, &delete_pending,
6282                                        &write_time_ts);
6283                 }
6284
6285                 if (delete_pending) {
6286                         reply_nterror(req, NT_STATUS_DELETE_PENDING);
6287                         return;
6288                 }
6289         }
6290
6291         DEBUG(3,("call_trans2qfilepathinfo %s (%s) level=%d call=%d "
6292                  "total_data=%d\n", smb_fname_str_dbg(smb_fname),
6293                  fsp_fnum_dbg(fsp),
6294                  info_level,tran_call,total_data));
6295
6296         /* Pull out any data sent here before we realloc. */
6297         switch (info_level) {
6298                 case SMB_INFO_QUERY_EAS_FROM_LIST:
6299                 {
6300                         /* Pull any EA list from the data portion. */
6301                         uint32_t ea_size;
6302
6303                         if (total_data < 4) {
6304                                 reply_nterror(
6305                                         req, NT_STATUS_INVALID_PARAMETER);
6306                                 return;
6307                         }
6308                         ea_size = IVAL(pdata,0);
6309
6310                         if (total_data > 0 && ea_size != total_data) {
6311                                 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
6312 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
6313                                 reply_nterror(
6314                                         req, NT_STATUS_INVALID_PARAMETER);
6315                                 return;
6316                         }
6317
6318                         if (!lp_ea_support(SNUM(conn))) {
6319                                 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
6320                                 return;
6321                         }
6322
6323                         /* Pull out the list of names. */
6324                         ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4);
6325                         if (!ea_list) {
6326                                 reply_nterror(
6327                                         req, NT_STATUS_INVALID_PARAMETER);
6328                                 return;
6329                         }
6330                         break;
6331                 }
6332
6333                 case SMB_QUERY_POSIX_LOCK:
6334                 {
6335                         if (fsp == NULL ||
6336                             fsp->fsp_flags.is_pathref ||
6337                             fsp_get_io_fd(fsp) == -1)
6338                         {
6339                                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
6340                                 return;
6341                         }
6342
6343                         if (total_data != POSIX_LOCK_DATA_SIZE) {
6344                                 reply_nterror(
6345                                         req, NT_STATUS_INVALID_PARAMETER);
6346                                 return;
6347                         }
6348
6349                         /* Copy the lock range data. */
6350                         lock_data = (char *)talloc_memdup(
6351                                 req, pdata, total_data);
6352                         if (!lock_data) {
6353                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
6354                                 return;
6355                         }
6356                         lock_data_count = total_data;
6357                 }
6358                 default:
6359                         break;
6360         }
6361
6362         *pparams = (char *)SMB_REALLOC(*pparams,2);
6363         if (*pparams == NULL) {
6364                 reply_nterror(req, NT_STATUS_NO_MEMORY);
6365                 return;
6366         }
6367         params = *pparams;
6368         SSVAL(params,0,0);
6369
6370         /*
6371          * draft-leach-cifs-v1-spec-02.txt
6372          * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
6373          * says:
6374          *
6375          *  The requested information is placed in the Data portion of the
6376          *  transaction response. For the information levels greater than 0x100,
6377          *  the transaction response has 1 parameter word which should be
6378          *  ignored by the client.
6379          *
6380          * However Windows only follows this rule for the IS_NAME_VALID call.
6381          */
6382         switch (info_level) {
6383         case SMB_INFO_IS_NAME_VALID:
6384                 param_size = 0;
6385                 break;
6386         }
6387
6388         if ((info_level & SMB2_INFO_SPECIAL) == SMB2_INFO_SPECIAL) {
6389                 /*
6390                  * We use levels that start with 0xFF00
6391                  * internally to represent SMB2 specific levels
6392                  */
6393                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
6394                 return;
6395         }
6396
6397         status = smbd_do_qfilepathinfo(conn, req, req, info_level,
6398                                        fsp, smb_fname,
6399                                        delete_pending, write_time_ts,
6400                                        ea_list,
6401                                        lock_data_count, lock_data,
6402                                        req->flags2, max_data_bytes,
6403                                        &fixed_portion,
6404                                        ppdata, &data_size);
6405         if (!NT_STATUS_IS_OK(status)) {
6406                 if (open_was_deferred(req->xconn, req->mid)) {
6407                         /* We have re-scheduled this call. */
6408                         return;
6409                 }
6410                 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6411                         bool ok = defer_smb1_sharing_violation(req);
6412                         if (ok) {
6413                                 return;
6414                         }
6415                 }
6416                 reply_nterror(req, status);
6417                 return;
6418         }
6419         if (fixed_portion > max_data_bytes) {
6420                 reply_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH);
6421                 return;
6422         }
6423
6424         send_trans2_replies(conn, req, NT_STATUS_OK, params, param_size, *ppdata, data_size,
6425                             max_data_bytes);
6426
6427         return;
6428 }
6429
6430 /****************************************************************************
6431  Set a hard link (called by UNIX extensions and by NT rename with HARD link
6432  code.
6433 ****************************************************************************/
6434
6435 NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
6436                 connection_struct *conn,
6437                 struct smb_request *req,
6438                 bool overwrite_if_exists,
6439                 const struct smb_filename *smb_fname_old,
6440                 struct smb_filename *smb_fname_new)
6441 {
6442         NTSTATUS status = NT_STATUS_OK;
6443         int ret;
6444         bool ok;
6445
6446         /* source must already exist. */
6447         if (!VALID_STAT(smb_fname_old->st)) {
6448                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6449         }
6450
6451         if (VALID_STAT(smb_fname_new->st)) {
6452                 if (overwrite_if_exists) {
6453                         if (S_ISDIR(smb_fname_new->st.st_ex_mode)) {
6454                                 return NT_STATUS_FILE_IS_A_DIRECTORY;
6455                         }
6456                         status = unlink_internals(conn,
6457                                                 req,
6458                                                 FILE_ATTRIBUTE_NORMAL,
6459                                                 smb_fname_new,
6460                                                 false);
6461                         if (!NT_STATUS_IS_OK(status)) {
6462                                 return status;
6463                         }
6464                 } else {
6465                         /* Disallow if newname already exists. */
6466                         return NT_STATUS_OBJECT_NAME_COLLISION;
6467                 }
6468         }
6469
6470         /* No links from a directory. */
6471         if (S_ISDIR(smb_fname_old->st.st_ex_mode)) {
6472                 return NT_STATUS_FILE_IS_A_DIRECTORY;
6473         }
6474
6475         /* Setting a hardlink to/from a stream isn't currently supported. */
6476         ok = is_ntfs_stream_smb_fname(smb_fname_old);
6477         if (ok) {
6478                 DBG_DEBUG("Old name has streams\n");
6479                 return NT_STATUS_INVALID_PARAMETER;
6480         }
6481         ok = is_ntfs_stream_smb_fname(smb_fname_new);
6482         if (ok) {
6483                 DBG_DEBUG("New name has streams\n");
6484                 return NT_STATUS_INVALID_PARAMETER;
6485         }
6486
6487         DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
6488                   smb_fname_old->base_name, smb_fname_new->base_name));
6489
6490         ret = SMB_VFS_LINKAT(conn,
6491                         conn->cwd_fsp,
6492                         smb_fname_old,
6493                         conn->cwd_fsp,
6494                         smb_fname_new,
6495                         0);
6496
6497         if (ret != 0) {
6498                 status = map_nt_error_from_unix(errno);
6499                 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
6500                          nt_errstr(status), smb_fname_old->base_name,
6501                          smb_fname_new->base_name));
6502         }
6503         return status;
6504 }
6505
6506 /****************************************************************************
6507  Deal with setting the time from any of the setfilepathinfo functions.
6508  NOTE !!!! The check for FILE_WRITE_ATTRIBUTES access must be done *before*
6509  calling this function.
6510 ****************************************************************************/
6511
6512 NTSTATUS smb_set_file_time(connection_struct *conn,
6513                            files_struct *fsp,
6514                            const struct smb_filename *smb_fname,
6515                            struct smb_file_time *ft,
6516                            bool setting_write_time)
6517 {
6518         struct smb_filename smb_fname_base;
6519         struct timeval_buf tbuf[4];
6520         uint32_t action =
6521                 FILE_NOTIFY_CHANGE_LAST_ACCESS
6522                 |FILE_NOTIFY_CHANGE_LAST_WRITE
6523                 |FILE_NOTIFY_CHANGE_CREATION;
6524
6525         if (!VALID_STAT(smb_fname->st)) {
6526                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6527         }
6528
6529         /* get some defaults (no modifications) if any info is zero or -1. */
6530         if (is_omit_timespec(&ft->create_time)) {
6531                 action &= ~FILE_NOTIFY_CHANGE_CREATION;
6532         }
6533
6534         if (is_omit_timespec(&ft->atime)) {
6535                 action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
6536         }
6537
6538         if (is_omit_timespec(&ft->mtime)) {
6539                 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
6540         }
6541
6542         if (!setting_write_time) {
6543                 /* ft->mtime comes from change time, not write time. */
6544                 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
6545         }
6546
6547         /* Ensure the resolution is the correct for
6548          * what we can store on this filesystem. */
6549
6550         round_timespec(conn->ts_res, &ft->create_time);
6551         round_timespec(conn->ts_res, &ft->ctime);
6552         round_timespec(conn->ts_res, &ft->atime);
6553         round_timespec(conn->ts_res, &ft->mtime);
6554
6555         DBG_DEBUG("smb_set_filetime: actime: %s\n ",
6556                   timespec_string_buf(&ft->atime, true, &tbuf[0]));
6557         DBG_DEBUG("smb_set_filetime: modtime: %s\n ",
6558                   timespec_string_buf(&ft->mtime, true, &tbuf[1]));
6559         DBG_DEBUG("smb_set_filetime: ctime: %s\n ",
6560                   timespec_string_buf(&ft->ctime, true, &tbuf[2]));
6561         DBG_DEBUG("smb_set_file_time: createtime: %s\n ",
6562                   timespec_string_buf(&ft->create_time, true, &tbuf[3]));
6563
6564         if (setting_write_time) {
6565                 /*
6566                  * This was a Windows setfileinfo on an open file.
6567                  * NT does this a lot. We also need to 
6568                  * set the time here, as it can be read by 
6569                  * FindFirst/FindNext and with the patch for bug #2045
6570                  * in smbd/fileio.c it ensures that this timestamp is
6571                  * kept sticky even after a write. We save the request
6572                  * away and will set it on file close and after a write. JRA.
6573                  */
6574
6575                 DBG_DEBUG("setting pending modtime to %s\n",
6576                           timespec_string_buf(&ft->mtime, true, &tbuf[0]));
6577
6578                 if (fsp != NULL) {
6579                         if (fsp->base_fsp) {
6580                                 set_sticky_write_time_fsp(fsp->base_fsp,
6581                                                           ft->mtime);
6582                         } else {
6583                                 set_sticky_write_time_fsp(fsp, ft->mtime);
6584                         }
6585                 } else {
6586                         set_sticky_write_time_path(
6587                                 vfs_file_id_from_sbuf(conn, &smb_fname->st),
6588                                 ft->mtime);
6589                 }
6590         }
6591
6592         DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
6593
6594         /* Always call ntimes on the base, even if a stream was passed in. */
6595         smb_fname_base = *smb_fname;
6596         smb_fname_base.stream_name = NULL;
6597
6598         if(file_ntimes(conn, &smb_fname_base, ft)!=0) {
6599                 return map_nt_error_from_unix(errno);
6600         }
6601
6602         notify_fname(conn, NOTIFY_ACTION_MODIFIED, action,
6603                      smb_fname->base_name);
6604         return NT_STATUS_OK;
6605 }
6606
6607 /****************************************************************************
6608  Deal with setting the dosmode from any of the setfilepathinfo functions.
6609  NB. The check for FILE_WRITE_ATTRIBUTES access on this path must have been
6610  done before calling this function.
6611 ****************************************************************************/
6612
6613 static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
6614                                      const struct smb_filename *smb_fname,
6615                                      uint32_t dosmode)
6616 {
6617         struct smb_filename *smb_fname_base;
6618         NTSTATUS status;
6619
6620         if (!VALID_STAT(smb_fname->st)) {
6621                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6622         }
6623
6624         /* Always operate on the base_name, even if a stream was passed in. */
6625         smb_fname_base = synthetic_smb_fname(talloc_tos(),
6626                                         smb_fname->base_name,
6627                                         NULL,
6628                                         &smb_fname->st,
6629                                         smb_fname->twrp,
6630                                         smb_fname->flags);
6631         if (smb_fname_base == NULL) {
6632                 return NT_STATUS_NO_MEMORY;
6633         }
6634
6635         if (dosmode) {
6636                 if (S_ISDIR(smb_fname_base->st.st_ex_mode)) {
6637                         dosmode |= FILE_ATTRIBUTE_DIRECTORY;
6638                 } else {
6639                         dosmode &= ~FILE_ATTRIBUTE_DIRECTORY;
6640                 }
6641         }
6642
6643         DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode));
6644
6645         /* check the mode isn't different, before changing it */
6646         if ((dosmode != 0) && (dosmode != dos_mode(conn, smb_fname_base))) {
6647                 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
6648                           "0x%x\n", smb_fname_str_dbg(smb_fname_base),
6649                           (unsigned int)dosmode));
6650
6651                 if(file_set_dosmode(conn, smb_fname_base, dosmode, NULL,
6652                                     false)) {
6653                         DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
6654                                  "%s failed (%s)\n",
6655                                  smb_fname_str_dbg(smb_fname_base),
6656                                  strerror(errno)));
6657                         status = map_nt_error_from_unix(errno);
6658                         goto out;
6659                 }
6660         }
6661         status = NT_STATUS_OK;
6662  out:
6663         TALLOC_FREE(smb_fname_base);
6664         return status;
6665 }
6666
6667 /****************************************************************************
6668  Deal with setting the size from any of the setfilepathinfo functions.
6669 ****************************************************************************/
6670
6671 static NTSTATUS smb_set_file_size(connection_struct *conn,
6672                                   struct smb_request *req,
6673                                   files_struct *fsp,
6674                                   const struct smb_filename *smb_fname,
6675                                   const SMB_STRUCT_STAT *psbuf,
6676                                   off_t size,
6677                                   bool fail_after_createfile)
6678 {
6679         NTSTATUS status = NT_STATUS_OK;
6680         struct smb_filename *smb_fname_tmp = NULL;
6681         files_struct *new_fsp = NULL;
6682
6683         if (!VALID_STAT(*psbuf)) {
6684                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6685         }
6686
6687         DBG_INFO("size: %"PRIu64", file_size_stat=%"PRIu64"\n",
6688                  (uint64_t)size,
6689                  get_file_size_stat(psbuf));
6690
6691         if (size == get_file_size_stat(psbuf)) {
6692                 if (fsp == NULL) {
6693                         return NT_STATUS_OK;
6694                 }
6695                 if (!fsp->fsp_flags.modified) {
6696                         return NT_STATUS_OK;
6697                 }
6698                 trigger_write_time_update_immediate(fsp);
6699                 return NT_STATUS_OK;
6700         }
6701
6702         DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
6703                   smb_fname_str_dbg(smb_fname), (double)size));
6704
6705         if (fsp &&
6706             !fsp->fsp_flags.is_pathref &&
6707             fsp_get_io_fd(fsp) != -1)
6708         {
6709                 /* Handle based call. */
6710                 if (!(fsp->access_mask & FILE_WRITE_DATA)) {
6711                         return NT_STATUS_ACCESS_DENIED;
6712                 }
6713
6714                 if (vfs_set_filelen(fsp, size) == -1) {
6715                         return map_nt_error_from_unix(errno);
6716                 }
6717                 trigger_write_time_update_immediate(fsp);
6718                 return NT_STATUS_OK;
6719         }
6720
6721         smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
6722         if (smb_fname_tmp == NULL) {
6723                 return NT_STATUS_NO_MEMORY;
6724         }
6725
6726         smb_fname_tmp->st = *psbuf;
6727
6728         status = SMB_VFS_CREATE_FILE(
6729                 conn,                                   /* conn */
6730                 req,                                    /* req */
6731                 smb_fname_tmp,                          /* fname */
6732                 FILE_WRITE_DATA,                        /* access_mask */
6733                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
6734                     FILE_SHARE_DELETE),
6735                 FILE_OPEN,                              /* create_disposition*/
6736                 0,                                      /* create_options */
6737                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
6738                 0,                                      /* oplock_request */
6739                 NULL,                                   /* lease */
6740                 0,                                      /* allocation_size */
6741                 0,                                      /* private_flags */
6742                 NULL,                                   /* sd */
6743                 NULL,                                   /* ea_list */
6744                 &new_fsp,                               /* result */
6745                 NULL,                                   /* pinfo */
6746                 NULL, NULL);                            /* create context */
6747
6748         TALLOC_FREE(smb_fname_tmp);
6749
6750         if (!NT_STATUS_IS_OK(status)) {
6751                 /* NB. We check for open_was_deferred in the caller. */
6752                 return status;
6753         }
6754
6755         /* See RAW-SFILEINFO-END-OF-FILE */
6756         if (fail_after_createfile) {
6757                 close_file(req, new_fsp,NORMAL_CLOSE);
6758                 return NT_STATUS_INVALID_LEVEL;
6759         }
6760
6761         if (vfs_set_filelen(new_fsp, size) == -1) {
6762                 status = map_nt_error_from_unix(errno);
6763                 close_file(req, new_fsp,NORMAL_CLOSE);
6764                 return status;
6765         }
6766
6767         trigger_write_time_update_immediate(new_fsp);
6768         close_file(req, new_fsp,NORMAL_CLOSE);
6769         return NT_STATUS_OK;
6770 }
6771
6772 /****************************************************************************
6773  Deal with SMB_INFO_SET_EA.
6774 ****************************************************************************/
6775
6776 static NTSTATUS smb_info_set_ea(connection_struct *conn,
6777                                 const char *pdata,
6778                                 int total_data,
6779                                 files_struct *fsp,
6780                                 const struct smb_filename *smb_fname)
6781 {
6782         struct ea_list *ea_list = NULL;
6783         TALLOC_CTX *ctx = NULL;
6784         NTSTATUS status = NT_STATUS_OK;
6785
6786         if (total_data < 10) {
6787
6788                 /* OS/2 workplace shell seems to send SET_EA requests of "null"
6789                    length. They seem to have no effect. Bug #3212. JRA */
6790
6791                 if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
6792                         /* We're done. We only get EA info in this call. */
6793                         return NT_STATUS_OK;
6794                 }
6795
6796                 return NT_STATUS_INVALID_PARAMETER;
6797         }
6798
6799         if (IVAL(pdata,0) > total_data) {
6800                 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
6801                         IVAL(pdata,0), (unsigned int)total_data));
6802                 return NT_STATUS_INVALID_PARAMETER;
6803         }
6804
6805         ctx = talloc_tos();
6806         ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
6807         if (!ea_list) {
6808                 return NT_STATUS_INVALID_PARAMETER;
6809         }
6810
6811         status = set_ea(conn, fsp, smb_fname, ea_list);
6812
6813         return status;
6814 }
6815
6816 /****************************************************************************
6817  Deal with SMB_FILE_FULL_EA_INFORMATION set.
6818 ****************************************************************************/
6819
6820 static NTSTATUS smb_set_file_full_ea_info(connection_struct *conn,
6821                                 const char *pdata,
6822                                 int total_data,
6823                                 files_struct *fsp)
6824 {
6825         struct ea_list *ea_list = NULL;
6826         NTSTATUS status;
6827
6828         if (!fsp) {
6829                 return NT_STATUS_INVALID_HANDLE;
6830         }
6831
6832         if (!lp_ea_support(SNUM(conn))) {
6833                 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
6834                         "EA's not supported.\n",
6835                         (unsigned int)total_data));
6836                 return NT_STATUS_EAS_NOT_SUPPORTED;
6837         }
6838
6839         if (total_data < 10) {
6840                 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
6841                         "too small.\n",
6842                         (unsigned int)total_data));
6843                 return NT_STATUS_INVALID_PARAMETER;
6844         }
6845
6846         ea_list = read_nttrans_ea_list(talloc_tos(),
6847                                 pdata,
6848                                 total_data);
6849
6850         if (!ea_list) {
6851                 return NT_STATUS_INVALID_PARAMETER;
6852         }
6853
6854         status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
6855
6856         DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
6857                 smb_fname_str_dbg(fsp->fsp_name),
6858                 nt_errstr(status) ));
6859
6860         return status;
6861 }
6862
6863
6864 /****************************************************************************
6865  Deal with SMB_SET_FILE_DISPOSITION_INFO.
6866 ****************************************************************************/
6867
6868 static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
6869                                 const char *pdata,
6870                                 int total_data,
6871                                 files_struct *fsp,
6872                                 struct smb_filename *smb_fname)
6873 {
6874         NTSTATUS status = NT_STATUS_OK;
6875         bool delete_on_close;
6876         uint32_t dosmode = 0;
6877
6878         if (total_data < 1) {
6879                 return NT_STATUS_INVALID_PARAMETER;
6880         }
6881
6882         if (fsp == NULL) {
6883                 return NT_STATUS_INVALID_HANDLE;
6884         }
6885
6886         delete_on_close = (CVAL(pdata,0) ? True : False);
6887         dosmode = dos_mode(conn, smb_fname);
6888
6889         DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
6890                 "delete_on_close = %u\n",
6891                 smb_fname_str_dbg(smb_fname),
6892                 (unsigned int)dosmode,
6893                 (unsigned int)delete_on_close ));
6894
6895         if (delete_on_close) {
6896                 status = can_set_delete_on_close(fsp, dosmode);
6897                 if (!NT_STATUS_IS_OK(status)) {
6898                         return status;
6899                 }
6900         }
6901
6902         /* The set is across all open files on this dev/inode pair. */
6903         if (!set_delete_on_close(fsp, delete_on_close,
6904                                  conn->session_info->security_token,
6905                                  conn->session_info->unix_token)) {
6906                 return NT_STATUS_ACCESS_DENIED;
6907         }
6908         return NT_STATUS_OK;
6909 }
6910
6911 /****************************************************************************
6912  Deal with SMB_FILE_POSITION_INFORMATION.
6913 ****************************************************************************/
6914
6915 static NTSTATUS smb_file_position_information(connection_struct *conn,
6916                                 const char *pdata,
6917                                 int total_data,
6918                                 files_struct *fsp)
6919 {
6920         uint64_t position_information;
6921
6922         if (total_data < 8) {
6923                 return NT_STATUS_INVALID_PARAMETER;
6924         }
6925
6926         if (fsp == NULL) {
6927                 /* Ignore on pathname based set. */
6928                 return NT_STATUS_OK;
6929         }
6930
6931         position_information = (uint64_t)IVAL(pdata,0);
6932         position_information |= (((uint64_t)IVAL(pdata,4)) << 32);
6933
6934         DEBUG(10,("smb_file_position_information: Set file position "
6935                   "information for file %s to %.0f\n", fsp_str_dbg(fsp),
6936                   (double)position_information));
6937         fh_set_position_information(fsp->fh, position_information);
6938         return NT_STATUS_OK;
6939 }
6940
6941 /****************************************************************************
6942  Deal with SMB_FILE_MODE_INFORMATION.
6943 ****************************************************************************/
6944
6945 static NTSTATUS smb_file_mode_information(connection_struct *conn,
6946                                 const char *pdata,
6947                                 int total_data)
6948 {
6949         uint32_t mode;
6950
6951         if (total_data < 4) {
6952                 return NT_STATUS_INVALID_PARAMETER;
6953         }
6954         mode = IVAL(pdata,0);
6955         if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
6956                 return NT_STATUS_INVALID_PARAMETER;
6957         }
6958         return NT_STATUS_OK;
6959 }
6960
6961 /****************************************************************************
6962  Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
6963 ****************************************************************************/
6964
6965 static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
6966                                        struct smb_request *req,
6967                                        const char *pdata,
6968                                        int total_data,
6969                                        const struct smb_filename *new_smb_fname)
6970 {
6971         char *link_target = NULL;
6972         struct smb_filename target_fname;
6973         TALLOC_CTX *ctx = talloc_tos();
6974         NTSTATUS status;
6975         int ret;
6976
6977         /* Set a symbolic link. */
6978         /* Don't allow this if follow links is false. */
6979
6980         if (total_data == 0) {
6981                 return NT_STATUS_INVALID_PARAMETER;
6982         }
6983
6984         if (!lp_follow_symlinks(SNUM(conn))) {
6985                 return NT_STATUS_ACCESS_DENIED;
6986         }
6987
6988         srvstr_pull_talloc(ctx, pdata, req->flags2, &link_target, pdata,
6989                     total_data, STR_TERMINATE);
6990
6991         if (!link_target) {
6992                 return NT_STATUS_INVALID_PARAMETER;
6993         }
6994
6995         target_fname = (struct smb_filename) {
6996                 .base_name = link_target,
6997         };
6998
6999         /* Removes @GMT tokens if any */
7000         status = canonicalize_snapshot_path(&target_fname, UCF_GMT_PATHNAME, 0);
7001         if (!NT_STATUS_IS_OK(status)) {
7002                 return status;
7003         }
7004
7005         DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
7006                         new_smb_fname->base_name, link_target ));
7007
7008         ret = SMB_VFS_SYMLINKAT(conn,
7009                         &target_fname,
7010                         conn->cwd_fsp,
7011                         new_smb_fname);
7012         if (ret != 0) {
7013                 return map_nt_error_from_unix(errno);
7014         }
7015
7016         return NT_STATUS_OK;
7017 }
7018
7019 /****************************************************************************
7020  Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
7021 ****************************************************************************/
7022
7023 static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
7024                                         struct smb_request *req,
7025                                         const char *pdata, int total_data,
7026                                         struct smb_filename *smb_fname_new)
7027 {
7028         char *oldname = NULL;
7029         struct smb_filename *smb_fname_old = NULL;
7030         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
7031         TALLOC_CTX *ctx = talloc_tos();
7032         NTSTATUS status = NT_STATUS_OK;
7033
7034         /* Set a hard link. */
7035         if (total_data == 0) {
7036                 return NT_STATUS_INVALID_PARAMETER;
7037         }
7038
7039         if (req->posix_pathnames) {
7040                 srvstr_get_path_posix(ctx,
7041                         pdata,
7042                         req->flags2,
7043                         &oldname,
7044                         pdata,
7045                         total_data,
7046                         STR_TERMINATE,
7047                         &status);
7048         } else {
7049                 srvstr_get_path(ctx,
7050                         pdata,
7051                         req->flags2,
7052                         &oldname,
7053                         pdata,
7054                         total_data,
7055                         STR_TERMINATE,
7056                         &status);
7057         }
7058         if (!NT_STATUS_IS_OK(status)) {
7059                 return status;
7060         }
7061
7062         DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
7063                 smb_fname_str_dbg(smb_fname_new), oldname));
7064
7065         status = filename_convert(ctx,
7066                                 conn,
7067                                 oldname,
7068                                 ucf_flags,
7069                                 0,
7070                                 &smb_fname_old);
7071         if (!NT_STATUS_IS_OK(status)) {
7072                 return status;
7073         }
7074
7075         return hardlink_internals(ctx, conn, req, false,
7076                         smb_fname_old, smb_fname_new);
7077 }
7078
7079 /****************************************************************************
7080  Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
7081 ****************************************************************************/
7082
7083 static NTSTATUS smb2_file_rename_information(connection_struct *conn,
7084                                             struct smb_request *req,
7085                                             const char *pdata,
7086                                             int total_data,
7087                                             files_struct *fsp,
7088                                             struct smb_filename *smb_fname_src)
7089 {
7090         bool overwrite;
7091         uint32_t len;
7092         char *newname = NULL;
7093         struct smb_filename *smb_fname_dst = NULL;
7094         const char *dst_original_lcomp = NULL;
7095         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
7096         NTSTATUS status = NT_STATUS_OK;
7097         TALLOC_CTX *ctx = talloc_tos();
7098
7099         if (!fsp) {
7100                 return NT_STATUS_INVALID_HANDLE;
7101         }
7102
7103         if (total_data < 20) {
7104                 return NT_STATUS_INVALID_PARAMETER;
7105         }
7106
7107         overwrite = (CVAL(pdata,0) ? True : False);
7108         len = IVAL(pdata,16);
7109
7110         if (len > (total_data - 20) || (len == 0)) {
7111                 return NT_STATUS_INVALID_PARAMETER;
7112         }
7113
7114         if (req->posix_pathnames) {
7115                 srvstr_get_path_posix(ctx,
7116                                 pdata,
7117                                 req->flags2,
7118                                 &newname,
7119                                 &pdata[20],
7120                                 len,
7121                                 STR_TERMINATE,
7122                                 &status);
7123         } else {
7124                 srvstr_get_path(ctx,
7125                                 pdata,
7126                                 req->flags2,
7127                                 &newname,
7128                                 &pdata[20],
7129                                 len,
7130                                 STR_TERMINATE,
7131                                 &status);
7132         }
7133         if (!NT_STATUS_IS_OK(status)) {
7134                 return status;
7135         }
7136
7137         DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
7138                                 newname));
7139
7140         status = filename_convert(ctx,
7141                                 conn,
7142                                 newname,
7143                                 ucf_flags,
7144                                 0,
7145                                 &smb_fname_dst);
7146         if (!NT_STATUS_IS_OK(status)) {
7147                 return status;
7148         }
7149
7150         if (fsp->base_fsp) {
7151                 /* newname must be a stream name. */
7152                 if (newname[0] != ':') {
7153                         return NT_STATUS_NOT_SUPPORTED;
7154                 }
7155
7156                 /* Create an smb_fname to call rename_internals_fsp() with. */
7157                 smb_fname_dst = synthetic_smb_fname(talloc_tos(),
7158                                         fsp->base_fsp->fsp_name->base_name,
7159                                         newname,
7160                                         NULL,
7161                                         fsp->base_fsp->fsp_name->twrp,
7162                                         fsp->base_fsp->fsp_name->flags);
7163                 if (smb_fname_dst == NULL) {
7164                         status = NT_STATUS_NO_MEMORY;
7165                         goto out;
7166                 }
7167         }
7168
7169         /*
7170          * Set the original last component, since
7171          * rename_internals_fsp() requires it.
7172          */
7173         dst_original_lcomp = get_original_lcomp(smb_fname_dst,
7174                                         conn,
7175                                         newname,
7176                                         ucf_flags);
7177         if (dst_original_lcomp == NULL) {
7178                 status = NT_STATUS_NO_MEMORY;
7179                 goto out;
7180         }
7181
7182         DEBUG(10,("smb2_file_rename_information: "
7183                   "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
7184                   fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
7185                   smb_fname_str_dbg(smb_fname_dst)));
7186         status = rename_internals_fsp(conn,
7187                                 fsp,
7188                                 smb_fname_dst,
7189                                 dst_original_lcomp,
7190                                 (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM),
7191                                 overwrite);
7192
7193  out:
7194         TALLOC_FREE(smb_fname_dst);
7195         return status;
7196 }
7197
7198 static NTSTATUS smb_file_link_information(connection_struct *conn,
7199                                             struct smb_request *req,
7200                                             const char *pdata,
7201                                             int total_data,
7202                                             files_struct *fsp,
7203                                             struct smb_filename *smb_fname_src)
7204 {
7205         bool overwrite;
7206         uint32_t len;
7207         char *newname = NULL;
7208         struct smb_filename *smb_fname_dst = NULL;
7209         NTSTATUS status = NT_STATUS_OK;
7210         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
7211         TALLOC_CTX *ctx = talloc_tos();
7212
7213         if (!fsp) {
7214                 return NT_STATUS_INVALID_HANDLE;
7215         }
7216
7217         if (total_data < 20) {
7218                 return NT_STATUS_INVALID_PARAMETER;
7219         }
7220
7221         overwrite = (CVAL(pdata,0) ? true : false);
7222         len = IVAL(pdata,16);
7223
7224         if (len > (total_data - 20) || (len == 0)) {
7225                 return NT_STATUS_INVALID_PARAMETER;
7226         }
7227
7228         if (smb_fname_src->flags & SMB_FILENAME_POSIX_PATH) {
7229                 srvstr_get_path_posix(ctx,
7230                                 pdata,
7231                                 req->flags2,
7232                                 &newname,
7233                                 &pdata[20],
7234                                 len,
7235                                 STR_TERMINATE,
7236                                 &status);
7237                 ucf_flags |= UCF_POSIX_PATHNAMES;
7238         } else {
7239                 srvstr_get_path(ctx,
7240                                 pdata,
7241                                 req->flags2,
7242                                 &newname,
7243                                 &pdata[20],
7244                                 len,
7245                                 STR_TERMINATE,
7246                                 &status);
7247         }
7248         if (!NT_STATUS_IS_OK(status)) {
7249                 return status;
7250         }
7251
7252         DEBUG(10,("smb_file_link_information: got name |%s|\n",
7253                                 newname));
7254
7255         status = filename_convert(ctx,
7256                                 conn,
7257                                 newname,
7258                                 ucf_flags,
7259                                 0,
7260                                 &smb_fname_dst);
7261         if (!NT_STATUS_IS_OK(status)) {
7262                 return status;
7263         }
7264
7265         if (fsp->base_fsp) {
7266                 /* No stream names. */
7267                 return NT_STATUS_NOT_SUPPORTED;
7268         }
7269
7270         DEBUG(10,("smb_file_link_information: "
7271                   "SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
7272                   fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
7273                   smb_fname_str_dbg(smb_fname_dst)));
7274         status = hardlink_internals(ctx,
7275                                 conn,
7276                                 req,
7277                                 overwrite,
7278                                 fsp->fsp_name,
7279                                 smb_fname_dst);
7280
7281         TALLOC_FREE(smb_fname_dst);
7282         return status;
7283 }
7284
7285 /****************************************************************************
7286  Deal with SMB_FILE_RENAME_INFORMATION.
7287 ****************************************************************************/
7288
7289 static NTSTATUS smb_file_rename_information(connection_struct *conn,
7290                                             struct smb_request *req,
7291                                             const char *pdata,
7292                                             int total_data,
7293                                             files_struct *fsp,
7294                                             struct smb_filename *smb_fname_src)
7295 {
7296         bool overwrite;
7297         uint32_t root_fid;
7298         uint32_t len;
7299         char *newname = NULL;
7300         struct smb_filename *smb_fname_dst = NULL;
7301         const char *dst_original_lcomp = NULL;
7302         NTSTATUS status = NT_STATUS_OK;
7303         char *p;
7304         TALLOC_CTX *ctx = talloc_tos();
7305
7306         if (total_data < 13) {
7307                 return NT_STATUS_INVALID_PARAMETER;
7308         }
7309
7310         overwrite = (CVAL(pdata,0) ? True : False);
7311         root_fid = IVAL(pdata,4);
7312         len = IVAL(pdata,8);
7313
7314         if (len > (total_data - 12) || (len == 0) || (root_fid != 0)) {
7315                 return NT_STATUS_INVALID_PARAMETER;
7316         }
7317
7318         if (req->posix_pathnames) {
7319                 srvstr_get_path_posix(ctx,
7320                                 pdata,
7321                                 req->flags2,
7322                                 &newname,
7323                                 &pdata[12],
7324                                 len,
7325                                 0,
7326                                 &status);
7327         } else {
7328                 srvstr_get_path(ctx,
7329                                 pdata,
7330                                 req->flags2,
7331                                 &newname,
7332                                 &pdata[12],
7333                                 len,
7334                                 0,
7335                                 &status);
7336         }
7337         if (!NT_STATUS_IS_OK(status)) {
7338                 return status;
7339         }
7340
7341         DEBUG(10,("smb_file_rename_information: got name |%s|\n",
7342                                 newname));
7343
7344         /* Check the new name has no '/' characters. */
7345         if (strchr_m(newname, '/')) {
7346                 return NT_STATUS_NOT_SUPPORTED;
7347         }
7348
7349         if (fsp && fsp->base_fsp) {
7350                 /* newname must be a stream name. */
7351                 if (newname[0] != ':') {
7352                         return NT_STATUS_NOT_SUPPORTED;
7353                 }
7354
7355                 /* Create an smb_fname to call rename_internals_fsp() with. */
7356                 smb_fname_dst = synthetic_smb_fname(talloc_tos(),
7357                                         fsp->base_fsp->fsp_name->base_name,
7358                                         newname,
7359                                         NULL,
7360                                         fsp->base_fsp->fsp_name->twrp,
7361                                         fsp->base_fsp->fsp_name->flags);
7362                 if (smb_fname_dst == NULL) {
7363                         status = NT_STATUS_NO_MEMORY;
7364                         goto out;
7365                 }
7366
7367                 /*
7368                  * Get the original last component, since
7369                  * rename_internals_fsp() requires it.
7370                  */
7371                 dst_original_lcomp = get_original_lcomp(smb_fname_dst,
7372                                         conn,
7373                                         newname,
7374                                         0);
7375                 if (dst_original_lcomp == NULL) {
7376                         status = NT_STATUS_NO_MEMORY;
7377                         goto out;
7378                 }
7379
7380         } else {
7381                 /*
7382                  * Build up an smb_fname_dst based on the filename passed in.
7383                  * We basically just strip off the last component, and put on
7384                  * the newname instead.
7385                  */
7386                 char *base_name = NULL;
7387                 uint32_t ucf_flags = UCF_ALWAYS_ALLOW_WCARD_LCOMP|
7388                                 ucf_flags_from_smb_request(req);
7389
7390                 /* newname must *not* be a stream name. */
7391                 if (newname[0] == ':') {
7392                         return NT_STATUS_NOT_SUPPORTED;
7393                 }
7394
7395                 /*
7396                  * Strip off the last component (filename) of the path passed
7397                  * in.
7398                  */
7399                 base_name = talloc_strdup(ctx, smb_fname_src->base_name);
7400                 if (!base_name) {
7401                         return NT_STATUS_NO_MEMORY;
7402                 }
7403                 p = strrchr_m(base_name, '/');
7404                 if (p) {
7405                         p[1] = '\0';
7406                 } else {
7407                         base_name = talloc_strdup(ctx, "");
7408                         if (!base_name) {
7409                                 return NT_STATUS_NO_MEMORY;
7410                         }
7411                 }
7412                 /* Append the new name. */
7413                 base_name = talloc_asprintf_append(base_name,
7414                                 "%s",
7415                                 newname);
7416                 if (!base_name) {
7417                         return NT_STATUS_NO_MEMORY;
7418                 }
7419
7420                 status = filename_convert(ctx,
7421                                           conn,
7422                                           base_name,
7423                                           ucf_flags,
7424                                           0,
7425                                           &smb_fname_dst);
7426
7427                 /* If an error we expect this to be
7428                  * NT_STATUS_OBJECT_PATH_NOT_FOUND */
7429
7430                 if (!NT_STATUS_IS_OK(status)) {
7431                         if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND,
7432                                             status)) {
7433                                 goto out;
7434                         }
7435                         /* Create an smb_fname to call rename_internals_fsp() */
7436                         smb_fname_dst = synthetic_smb_fname(ctx,
7437                                                 base_name,
7438                                                 NULL,
7439                                                 NULL,
7440                                                 smb_fname_src->twrp,
7441                                                 smb_fname_src->flags);
7442                         if (smb_fname_dst == NULL) {
7443                                 status = NT_STATUS_NO_MEMORY;
7444                                 goto out;
7445                         }
7446                 }
7447                 dst_original_lcomp = get_original_lcomp(smb_fname_dst,
7448                                         conn,
7449                                         newname,
7450                                         ucf_flags);
7451                 if (dst_original_lcomp == NULL) {
7452                         status = NT_STATUS_NO_MEMORY;
7453                         goto out;
7454                 }
7455         }
7456
7457         if (fsp) {
7458                 DEBUG(10,("smb_file_rename_information: "
7459                           "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
7460                           fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
7461                           smb_fname_str_dbg(smb_fname_dst)));
7462                 status = rename_internals_fsp(conn,
7463                                         fsp,
7464                                         smb_fname_dst,
7465                                         dst_original_lcomp,
7466                                         0,
7467                                         overwrite);
7468         } else {
7469                 DEBUG(10,("smb_file_rename_information: "
7470                           "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
7471                           smb_fname_str_dbg(smb_fname_src),
7472                           smb_fname_str_dbg(smb_fname_dst)));
7473                 status = rename_internals(ctx,
7474                                         conn,
7475                                         req,
7476                                         smb_fname_src,
7477                                         NULL,
7478                                         smb_fname_dst,
7479                                         dst_original_lcomp,
7480                                         0,
7481                                         overwrite,
7482                                         FILE_WRITE_ATTRIBUTES);
7483         }
7484  out:
7485         TALLOC_FREE(smb_fname_dst);
7486         return status;
7487 }
7488
7489 /****************************************************************************
7490  Deal with SMB_SET_POSIX_ACL.
7491 ****************************************************************************/
7492
7493 #if defined(HAVE_POSIX_ACLS)
7494 static NTSTATUS smb_set_posix_acl(connection_struct *conn,
7495                                 struct smb_request *req,
7496                                 const char *pdata,
7497                                 int total_data_in,
7498                                 files_struct *fsp,
7499                                 const struct smb_filename *smb_fname)
7500 {
7501         uint16_t posix_acl_version;
7502         uint16_t num_file_acls;
7503         uint16_t num_def_acls;
7504         bool valid_file_acls = true;
7505         bool valid_def_acls = true;
7506         NTSTATUS status;
7507         unsigned int size_needed;
7508         unsigned int total_data;
7509         bool close_fsp = false;
7510
7511         if (total_data_in < 0) {
7512                 status = NT_STATUS_INVALID_PARAMETER;
7513                 goto out;
7514         }
7515
7516         total_data = total_data_in;
7517
7518         if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
7519                 status = NT_STATUS_INVALID_PARAMETER;
7520                 goto out;
7521         }
7522         posix_acl_version = SVAL(pdata,0);
7523         num_file_acls = SVAL(pdata,2);
7524         num_def_acls = SVAL(pdata,4);
7525
7526         if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
7527                 valid_file_acls = false;
7528                 num_file_acls = 0;
7529         }
7530
7531         if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
7532                 valid_def_acls = false;
7533                 num_def_acls = 0;
7534         }
7535
7536         if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
7537                 status = NT_STATUS_INVALID_PARAMETER;
7538                 goto out;
7539         }
7540
7541         /* Wrap checks. */
7542         if (num_file_acls + num_def_acls < num_file_acls) {
7543                 status = NT_STATUS_INVALID_PARAMETER;
7544                 goto out;
7545         }
7546
7547         size_needed = num_file_acls + num_def_acls;
7548
7549         /*
7550          * (size_needed * SMB_POSIX_ACL_ENTRY_SIZE) must be less
7551          * than UINT_MAX, so check by division.
7552          */
7553         if (size_needed > (UINT_MAX/SMB_POSIX_ACL_ENTRY_SIZE)) {
7554                 status = NT_STATUS_INVALID_PARAMETER;
7555                 goto out;
7556         }
7557
7558         size_needed = size_needed*SMB_POSIX_ACL_ENTRY_SIZE;
7559         if (size_needed + SMB_POSIX_ACL_HEADER_SIZE < size_needed) {
7560                 status = NT_STATUS_INVALID_PARAMETER;
7561                 goto out;
7562         }
7563         size_needed += SMB_POSIX_ACL_HEADER_SIZE;
7564
7565         if (total_data < size_needed) {
7566                 status = NT_STATUS_INVALID_PARAMETER;
7567                 goto out;
7568         }
7569
7570         /*
7571          * Ensure we always operate on a file descriptor, not just
7572          * the filename.
7573          */
7574         if (fsp == NULL) {
7575                 uint32_t access_mask = SEC_STD_WRITE_OWNER|
7576                                         SEC_STD_WRITE_DAC|
7577                                         SEC_STD_READ_CONTROL|
7578                                         FILE_READ_ATTRIBUTES|
7579                                         FILE_WRITE_ATTRIBUTES;
7580
7581                 status = get_posix_fsp(conn,
7582                                         req,
7583                                         smb_fname,
7584                                         access_mask,
7585                                         &fsp);
7586
7587                 if (!NT_STATUS_IS_OK(status)) {
7588                         goto out;
7589                 }
7590                 close_fsp = true;
7591         }
7592
7593         /* Here we know fsp != NULL */
7594         SMB_ASSERT(fsp != NULL);
7595
7596         status = refuse_symlink(conn, fsp, fsp->fsp_name);
7597         if (!NT_STATUS_IS_OK(status)) {
7598                 goto out;
7599         }
7600
7601         /* If we have a default acl, this *must* be a directory. */
7602         if (valid_def_acls && !fsp->fsp_flags.is_directory) {
7603                 DBG_INFO("Can't set default acls on "
7604                          "non-directory %s\n",
7605                          fsp_str_dbg(fsp));
7606                 return NT_STATUS_INVALID_HANDLE;
7607         }
7608
7609         DBG_DEBUG("file %s num_file_acls = %"PRIu16", "
7610                   "num_def_acls = %"PRIu16"\n",
7611                   fsp_str_dbg(fsp),
7612                   num_file_acls,
7613                   num_def_acls);
7614
7615         /* Move pdata to the start of the file ACL entries. */
7616         pdata += SMB_POSIX_ACL_HEADER_SIZE;
7617
7618         if (valid_file_acls) {
7619                 status = set_unix_posix_acl(conn,
7620                                         fsp,
7621                                         num_file_acls,
7622                                         pdata);
7623                 if (!NT_STATUS_IS_OK(status)) {
7624                         goto out;
7625                 }
7626         }
7627
7628         /* Move pdata to the start of the default ACL entries. */
7629         pdata += (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE);
7630
7631         if (valid_def_acls) {
7632                 status = set_unix_posix_default_acl(conn,
7633                                         fsp,
7634                                         num_def_acls,
7635                                         pdata);
7636                 if (!NT_STATUS_IS_OK(status)) {
7637                         goto out;
7638                 }
7639         }
7640
7641         status = NT_STATUS_OK;
7642
7643   out:
7644
7645         if (close_fsp) {
7646                 (void)close_file(req, fsp, NORMAL_CLOSE);
7647                 fsp = NULL;
7648         }
7649         return status;
7650 }
7651 #endif
7652
7653 /****************************************************************************
7654  Deal with SMB_SET_POSIX_LOCK.
7655 ****************************************************************************/
7656
7657 static void smb_set_posix_lock_done(struct tevent_req *subreq);
7658
7659 static NTSTATUS smb_set_posix_lock(connection_struct *conn,
7660                                 struct smb_request *req,
7661                                 const char *pdata,
7662                                 int total_data,
7663                                 files_struct *fsp)
7664 {
7665         struct tevent_req *subreq = NULL;
7666         struct smbd_lock_element *lck = NULL;
7667         uint64_t count;
7668         uint64_t offset;
7669         uint64_t smblctx;
7670         bool blocking_lock = False;
7671         enum brl_type lock_type;
7672
7673         NTSTATUS status = NT_STATUS_OK;
7674
7675         if (fsp == NULL ||
7676             fsp->fsp_flags.is_pathref ||
7677             fsp_get_io_fd(fsp) == -1)
7678         {
7679                 return NT_STATUS_INVALID_HANDLE;
7680         }
7681
7682         if (total_data != POSIX_LOCK_DATA_SIZE) {
7683                 return NT_STATUS_INVALID_PARAMETER;
7684         }
7685
7686         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
7687                 case POSIX_LOCK_TYPE_READ:
7688                         lock_type = READ_LOCK;
7689                         break;
7690                 case POSIX_LOCK_TYPE_WRITE:
7691                         /* Return the right POSIX-mappable error code for files opened read-only. */
7692                         if (!fsp->fsp_flags.can_write) {
7693                                 return NT_STATUS_INVALID_HANDLE;
7694                         }
7695                         lock_type = WRITE_LOCK;
7696                         break;
7697                 case POSIX_LOCK_TYPE_UNLOCK:
7698                         lock_type = UNLOCK_LOCK;
7699                         break;
7700                 default:
7701                         return NT_STATUS_INVALID_PARAMETER;
7702         }
7703
7704         switch (SVAL(pdata, POSIX_LOCK_FLAGS_OFFSET)) {
7705         case POSIX_LOCK_FLAG_NOWAIT:
7706                 blocking_lock = false;
7707                 break;
7708         case POSIX_LOCK_FLAG_WAIT:
7709                 blocking_lock = true;
7710                 break;
7711         default:
7712                 return NT_STATUS_INVALID_PARAMETER;
7713         }
7714
7715         if (!lp_blocking_locks(SNUM(conn))) { 
7716                 blocking_lock = False;
7717         }
7718
7719         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
7720         offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
7721                         ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
7722         count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
7723                         ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
7724
7725         DBG_DEBUG("file %s, lock_type = %u, smblctx = %"PRIu64", "
7726                   "count = %"PRIu64", offset = %"PRIu64"\n",
7727                   fsp_str_dbg(fsp),
7728                   (unsigned int)lock_type,
7729                   smblctx,
7730                   count,
7731                   offset);
7732
7733         if (lock_type == UNLOCK_LOCK) {
7734                 struct smbd_lock_element l = {
7735                         .req_guid = smbd_request_guid(req, 0),
7736                         .smblctx = smblctx,
7737                         .brltype = UNLOCK_LOCK,
7738                         .offset = offset,
7739                         .count = count,
7740                 };
7741                 status = smbd_do_unlocking(req, fsp, 1, &l, POSIX_LOCK);
7742                 return status;
7743         }
7744
7745         lck = talloc(req, struct smbd_lock_element);
7746         if (lck == NULL) {
7747                 return NT_STATUS_NO_MEMORY;
7748         }
7749
7750         *lck = (struct smbd_lock_element) {
7751                 .req_guid = smbd_request_guid(req, 0),
7752                 .smblctx = smblctx,
7753                 .brltype = lock_type,
7754                 .count = count,
7755                 .offset = offset,
7756         };
7757
7758         subreq = smbd_smb1_do_locks_send(
7759                 fsp,
7760                 req->sconn->ev_ctx,
7761                 &req,
7762                 fsp,
7763                 blocking_lock ? UINT32_MAX : 0,
7764                 true,           /* large_offset */
7765                 POSIX_LOCK,
7766                 1,
7767                 lck);
7768         if (subreq == NULL) {
7769                 TALLOC_FREE(lck);
7770                 return NT_STATUS_NO_MEMORY;
7771         }
7772         tevent_req_set_callback(subreq, smb_set_posix_lock_done, req);
7773         return NT_STATUS_EVENT_PENDING;
7774 }
7775
7776 static void smb_set_posix_lock_done(struct tevent_req *subreq)
7777 {
7778         struct smb_request *req = NULL;
7779         NTSTATUS status;
7780         bool ok;
7781
7782         ok = smbd_smb1_do_locks_extract_smbreq(subreq, talloc_tos(), &req);
7783         SMB_ASSERT(ok);
7784
7785         status = smbd_smb1_do_locks_recv(subreq);
7786         TALLOC_FREE(subreq);
7787
7788         if (NT_STATUS_IS_OK(status)) {
7789                 char params[2] = {0};
7790                 /* Fake up max_data_bytes here - we know it fits. */
7791                 send_trans2_replies(
7792                         req->conn,
7793                         req,
7794                         NT_STATUS_OK,
7795                         params,
7796                         2,
7797                         NULL,
7798                         0,
7799                         0xffff);
7800         } else {
7801                 reply_nterror(req, status);
7802                 ok = srv_send_smb(
7803                         req->xconn,
7804                         (char *)req->outbuf,
7805                         true,
7806                         req->seqnum+1,
7807                         IS_CONN_ENCRYPTED(req->conn),
7808                         NULL);
7809                 if (!ok) {
7810                         exit_server_cleanly("smb_set_posix_lock_done: "
7811                                             "srv_send_smb failed.");
7812                 }
7813         }
7814
7815         TALLOC_FREE(req);
7816         return;
7817 }
7818
7819 /****************************************************************************
7820  Deal with SMB_SET_FILE_BASIC_INFO.
7821 ****************************************************************************/
7822
7823 static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
7824                                         const char *pdata,
7825                                         int total_data,
7826                                         files_struct *fsp,
7827                                         const struct smb_filename *smb_fname)
7828 {
7829         /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
7830         struct smb_file_time ft;
7831         uint32_t dosmode = 0;
7832         NTSTATUS status = NT_STATUS_OK;
7833
7834         init_smb_file_time(&ft);
7835
7836         if (total_data < 36) {
7837                 return NT_STATUS_INVALID_PARAMETER;
7838         }
7839
7840         if (fsp != NULL) {
7841                 status = check_access_fsp(fsp, FILE_WRITE_ATTRIBUTES);
7842         } else {
7843                 status = smbd_check_access_rights(conn,
7844                                 conn->cwd_fsp,
7845                                 smb_fname,
7846                                 false,
7847                                 FILE_WRITE_ATTRIBUTES);
7848         }
7849         if (!NT_STATUS_IS_OK(status)) {
7850                 return status;
7851         }
7852
7853         /* Set the attributes */
7854         dosmode = IVAL(pdata,32);
7855         status = smb_set_file_dosmode(conn, smb_fname, dosmode);
7856         if (!NT_STATUS_IS_OK(status)) {
7857                 return status;
7858         }
7859
7860         /* create time */
7861         ft.create_time = pull_long_date_full_timespec(pdata);
7862
7863         /* access time */
7864         ft.atime = pull_long_date_full_timespec(pdata+8);
7865
7866         /* write time. */
7867         ft.mtime = pull_long_date_full_timespec(pdata+16);
7868
7869         /* change time. */
7870         ft.ctime = pull_long_date_full_timespec(pdata+24);
7871
7872         DEBUG(10, ("smb_set_file_basic_info: file %s\n",
7873                    smb_fname_str_dbg(smb_fname)));
7874
7875         status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
7876         if (!NT_STATUS_IS_OK(status)) {
7877                 return status;
7878         }
7879
7880         if (fsp != NULL && fsp->fsp_flags.modified) {
7881                 trigger_write_time_update_immediate(fsp);
7882         }
7883         return NT_STATUS_OK;
7884 }
7885
7886 /****************************************************************************
7887  Deal with SMB_INFO_STANDARD.
7888 ****************************************************************************/
7889
7890 static NTSTATUS smb_set_info_standard(connection_struct *conn,
7891                                         const char *pdata,
7892                                         int total_data,
7893                                         files_struct *fsp,
7894                                         const struct smb_filename *smb_fname)
7895 {
7896         NTSTATUS status;
7897         struct smb_file_time ft;
7898
7899         init_smb_file_time(&ft);
7900
7901         if (total_data < 12) {
7902                 return NT_STATUS_INVALID_PARAMETER;
7903         }
7904
7905         /* create time */
7906         ft.create_time = time_t_to_full_timespec(srv_make_unix_date2(pdata));
7907         /* access time */
7908         ft.atime = time_t_to_full_timespec(srv_make_unix_date2(pdata+4));
7909         /* write time */
7910         ft.mtime = time_t_to_full_timespec(srv_make_unix_date2(pdata+8));
7911
7912         DEBUG(10,("smb_set_info_standard: file %s\n",
7913                 smb_fname_str_dbg(smb_fname)));
7914
7915         if (fsp != NULL) {
7916                 status = check_access_fsp(fsp, FILE_WRITE_ATTRIBUTES);
7917         } else {
7918                 status = smbd_check_access_rights(conn,
7919                                 conn->cwd_fsp,
7920                                 smb_fname,
7921                                 false,
7922                                 FILE_WRITE_ATTRIBUTES);
7923         }
7924         if (!NT_STATUS_IS_OK(status)) {
7925                 return status;
7926         }
7927
7928         status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
7929         if (!NT_STATUS_IS_OK(status)) {
7930                 return status;
7931         }
7932
7933         if (fsp != NULL && fsp->fsp_flags.modified) {
7934                 trigger_write_time_update_immediate(fsp);
7935         }
7936         return NT_STATUS_OK;
7937 }
7938
7939 /****************************************************************************
7940  Deal with SMB_SET_FILE_ALLOCATION_INFO.
7941 ****************************************************************************/
7942
7943 static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
7944                                              struct smb_request *req,
7945                                         const char *pdata,
7946                                         int total_data,
7947                                         files_struct *fsp,
7948                                         struct smb_filename *smb_fname)
7949 {
7950         uint64_t allocation_size = 0;
7951         NTSTATUS status = NT_STATUS_OK;
7952         files_struct *new_fsp = NULL;
7953
7954         if (!VALID_STAT(smb_fname->st)) {
7955                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
7956         }
7957
7958         if (total_data < 8) {
7959                 return NT_STATUS_INVALID_PARAMETER;
7960         }
7961
7962         allocation_size = (uint64_t)IVAL(pdata,0);
7963         allocation_size |= (((uint64_t)IVAL(pdata,4)) << 32);
7964         DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
7965                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
7966                   (double)allocation_size));
7967
7968         if (allocation_size) {
7969                 allocation_size = smb_roundup(conn, allocation_size);
7970         }
7971
7972         DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
7973                   "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname),
7974                   (double)allocation_size));
7975
7976         if (fsp &&
7977             !fsp->fsp_flags.is_pathref &&
7978             fsp_get_io_fd(fsp) != -1)
7979         {
7980                 /* Open file handle. */
7981                 if (!(fsp->access_mask & FILE_WRITE_DATA)) {
7982                         return NT_STATUS_ACCESS_DENIED;
7983                 }
7984
7985                 /* Only change if needed. */
7986                 if (allocation_size != get_file_size_stat(&smb_fname->st)) {
7987                         if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
7988                                 return map_nt_error_from_unix(errno);
7989                         }
7990                 }
7991                 /* But always update the time. */
7992                 /*
7993                  * This is equivalent to a write. Ensure it's seen immediately
7994                  * if there are no pending writes.
7995                  */
7996                 trigger_write_time_update_immediate(fsp);
7997                 return NT_STATUS_OK;
7998         }
7999
8000         /* Pathname or stat or directory file. */
8001         status = SMB_VFS_CREATE_FILE(
8002                 conn,                                   /* conn */
8003                 req,                                    /* req */
8004                 smb_fname,                              /* fname */
8005                 FILE_WRITE_DATA,                        /* access_mask */
8006                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
8007                     FILE_SHARE_DELETE),
8008                 FILE_OPEN,                              /* create_disposition*/
8009                 0,                                      /* create_options */
8010                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
8011                 0,                                      /* oplock_request */
8012                 NULL,                                   /* lease */
8013                 0,                                      /* allocation_size */
8014                 0,                                      /* private_flags */
8015                 NULL,                                   /* sd */
8016                 NULL,                                   /* ea_list */
8017                 &new_fsp,                               /* result */
8018                 NULL,                                   /* pinfo */
8019                 NULL, NULL);                            /* create context */
8020
8021         if (!NT_STATUS_IS_OK(status)) {
8022                 /* NB. We check for open_was_deferred in the caller. */
8023                 return status;
8024         }
8025
8026         /* Only change if needed. */
8027         if (allocation_size != get_file_size_stat(&smb_fname->st)) {
8028                 if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
8029                         status = map_nt_error_from_unix(errno);
8030                         close_file(req, new_fsp, NORMAL_CLOSE);
8031                         return status;
8032                 }
8033         }
8034
8035         /* Changing the allocation size should set the last mod time. */
8036         /*
8037          * This is equivalent to a write. Ensure it's seen immediately
8038          * if there are no pending writes.
8039          */
8040         trigger_write_time_update_immediate(new_fsp);
8041         close_file(req, new_fsp, NORMAL_CLOSE);
8042         return NT_STATUS_OK;
8043 }
8044
8045 /****************************************************************************
8046  Deal with SMB_SET_FILE_END_OF_FILE_INFO.
8047 ****************************************************************************/
8048
8049 static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
8050                                               struct smb_request *req,
8051                                         const char *pdata,
8052                                         int total_data,
8053                                         files_struct *fsp,
8054                                         const struct smb_filename *smb_fname,
8055                                         bool fail_after_createfile)
8056 {
8057         off_t size;
8058
8059         if (total_data < 8) {
8060                 return NT_STATUS_INVALID_PARAMETER;
8061         }
8062
8063         size = IVAL(pdata,0);
8064         size |= (((off_t)IVAL(pdata,4)) << 32);
8065         DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
8066                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
8067                   (double)size));
8068
8069         return smb_set_file_size(conn, req,
8070                                 fsp,
8071                                 smb_fname,
8072                                 &smb_fname->st,
8073                                 size,
8074                                 fail_after_createfile);
8075 }
8076
8077 /****************************************************************************
8078  Allow a UNIX info mknod.
8079 ****************************************************************************/
8080
8081 static NTSTATUS smb_unix_mknod(connection_struct *conn,
8082                                         const char *pdata,
8083                                         int total_data,
8084                                         const struct smb_filename *smb_fname)
8085 {
8086         uint32_t file_type = IVAL(pdata,56);
8087 #if defined(HAVE_MAKEDEV)
8088         uint32_t dev_major = IVAL(pdata,60);
8089         uint32_t dev_minor = IVAL(pdata,68);
8090 #endif
8091         SMB_DEV_T dev = (SMB_DEV_T)0;
8092         uint32_t raw_unixmode = IVAL(pdata,84);
8093         NTSTATUS status;
8094         mode_t unixmode;
8095         int ret;
8096
8097         if (total_data < 100) {
8098                 return NT_STATUS_INVALID_PARAMETER;
8099         }
8100
8101         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8102                                       PERM_NEW_FILE, &unixmode);
8103         if (!NT_STATUS_IS_OK(status)) {
8104                 return status;
8105         }
8106
8107 #if defined(HAVE_MAKEDEV)
8108         dev = makedev(dev_major, dev_minor);
8109 #endif
8110
8111         switch (file_type) {
8112                 /* We can't create other objects here. */
8113                 case UNIX_TYPE_FILE:
8114                 case UNIX_TYPE_DIR:
8115                 case UNIX_TYPE_SYMLINK:
8116                         return NT_STATUS_ACCESS_DENIED;
8117 #if defined(S_IFIFO)
8118                 case UNIX_TYPE_FIFO:
8119                         unixmode |= S_IFIFO;
8120                         break;
8121 #endif
8122 #if defined(S_IFSOCK)
8123                 case UNIX_TYPE_SOCKET:
8124                         unixmode |= S_IFSOCK;
8125                         break;
8126 #endif
8127 #if defined(S_IFCHR)
8128                 case UNIX_TYPE_CHARDEV:
8129                         /* This is only allowed for root. */
8130                         if (get_current_uid(conn) != sec_initial_uid()) {
8131                                 return NT_STATUS_ACCESS_DENIED;
8132                         }
8133                         unixmode |= S_IFCHR;
8134                         break;
8135 #endif
8136 #if defined(S_IFBLK)
8137                 case UNIX_TYPE_BLKDEV:
8138                         if (get_current_uid(conn) != sec_initial_uid()) {
8139                                 return NT_STATUS_ACCESS_DENIED;
8140                         }
8141                         unixmode |= S_IFBLK;
8142                         break;
8143 #endif
8144                 default:
8145                         return NT_STATUS_INVALID_PARAMETER;
8146         }
8147
8148         DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
8149                   "%.0f mode 0%o for file %s\n", (double)dev,
8150                   (unsigned int)unixmode, smb_fname_str_dbg(smb_fname)));
8151
8152         /* Ok - do the mknod. */
8153         ret = SMB_VFS_MKNODAT(conn,
8154                         conn->cwd_fsp,
8155                         smb_fname,
8156                         unixmode,
8157                         dev);
8158
8159         if (ret != 0) {
8160                 return map_nt_error_from_unix(errno);
8161         }
8162
8163         /* If any of the other "set" calls fail we
8164          * don't want to end up with a half-constructed mknod.
8165          */
8166
8167         if (lp_inherit_permissions(SNUM(conn))) {
8168                 struct smb_filename *parent_fname = NULL;
8169                 bool ok;
8170
8171                 ok = parent_smb_fname(talloc_tos(),
8172                                       smb_fname,
8173                                       &parent_fname,
8174                                       NULL);
8175                 if (!ok) {
8176                         return NT_STATUS_NO_MEMORY;
8177                 }
8178                 inherit_access_posix_acl(conn,
8179                                          parent_fname,
8180                                          smb_fname,
8181                                          unixmode);
8182                 TALLOC_FREE(parent_fname);
8183         }
8184
8185         return NT_STATUS_OK;
8186 }
8187
8188 /****************************************************************************
8189  Deal with SMB_SET_FILE_UNIX_BASIC.
8190 ****************************************************************************/
8191
8192 static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
8193                                         struct smb_request *req,
8194                                         const char *pdata,
8195                                         int total_data,
8196                                         files_struct *fsp,
8197                                         const struct smb_filename *smb_fname)
8198 {
8199         struct smb_file_time ft;
8200         uint32_t raw_unixmode;
8201         mode_t unixmode;
8202         off_t size = 0;
8203         uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
8204         gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
8205         NTSTATUS status = NT_STATUS_OK;
8206         enum perm_type ptype;
8207         files_struct *all_fsps = NULL;
8208         bool modify_mtime = true;
8209         struct file_id id;
8210         SMB_STRUCT_STAT sbuf;
8211
8212         init_smb_file_time(&ft);
8213
8214         if (total_data < 100) {
8215                 return NT_STATUS_INVALID_PARAMETER;
8216         }
8217
8218         if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
8219            IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
8220                 size=IVAL(pdata,0); /* first 8 Bytes are size */
8221                 size |= (((off_t)IVAL(pdata,4)) << 32);
8222         }
8223
8224         ft.atime = pull_long_date_full_timespec(pdata+24); /* access_time */
8225         ft.mtime = pull_long_date_full_timespec(pdata+32); /* modification_time */
8226         set_owner = (uid_t)IVAL(pdata,40);
8227         set_grp = (gid_t)IVAL(pdata,48);
8228         raw_unixmode = IVAL(pdata,84);
8229
8230         if (VALID_STAT(smb_fname->st)) {
8231                 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
8232                         ptype = PERM_EXISTING_DIR;
8233                 } else {
8234                         ptype = PERM_EXISTING_FILE;
8235                 }
8236         } else {
8237                 ptype = PERM_NEW_FILE;
8238         }
8239
8240         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8241                                       ptype, &unixmode);
8242         if (!NT_STATUS_IS_OK(status)) {
8243                 return status;
8244         }
8245
8246         DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
8247                   "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
8248                   smb_fname_str_dbg(smb_fname), (double)size,
8249                   (unsigned int)set_owner, (unsigned int)set_grp,
8250                   (int)raw_unixmode));
8251
8252         sbuf = smb_fname->st;
8253
8254         if (!VALID_STAT(sbuf)) {
8255                 /*
8256                  * The only valid use of this is to create character and block
8257                  * devices, and named pipes. This is deprecated (IMHO) and 
8258                  * a new info level should be used for mknod. JRA.
8259                  */
8260
8261                 return smb_unix_mknod(conn,
8262                                         pdata,
8263                                         total_data,
8264                                         smb_fname);
8265         }
8266
8267 #if 1
8268         /* Horrible backwards compatibility hack as an old server bug
8269          * allowed a CIFS client bug to remain unnoticed :-(. JRA.
8270          * */
8271
8272         if (!size) {
8273                 size = get_file_size_stat(&sbuf);
8274         }
8275 #endif
8276
8277         /*
8278          * Deal with the UNIX specific mode set.
8279          */
8280
8281         if (raw_unixmode != SMB_MODE_NO_CHANGE) {
8282                 int ret;
8283
8284                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
8285                           "setting mode 0%o for file %s\n",
8286                           (unsigned int)unixmode,
8287                           smb_fname_str_dbg(smb_fname)));
8288                 if (fsp &&
8289                     !fsp->fsp_flags.is_pathref &&
8290                     fsp_get_io_fd(fsp) != -1)
8291                 {
8292                         ret = SMB_VFS_FCHMOD(fsp, unixmode);
8293                 } else {
8294                         ret = SMB_VFS_CHMOD(conn, smb_fname, unixmode);
8295                 }
8296                 if (ret != 0) {
8297                         return map_nt_error_from_unix(errno);
8298                 }
8299         }
8300
8301         /*
8302          * Deal with the UNIX specific uid set.
8303          */
8304
8305         if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) &&
8306             (sbuf.st_ex_uid != set_owner)) {
8307                 int ret;
8308
8309                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
8310                           "changing owner %u for path %s\n",
8311                           (unsigned int)set_owner,
8312                           smb_fname_str_dbg(smb_fname)));
8313
8314                 if (fsp &&
8315                     !fsp->fsp_flags.is_pathref &&
8316                     fsp_get_io_fd(fsp) != -1)
8317                 {
8318                         ret = SMB_VFS_FCHOWN(fsp, set_owner, (gid_t)-1);
8319                 } else {
8320                         /*
8321                          * UNIX extensions calls must always operate
8322                          * on symlinks.
8323                          */
8324                         ret = SMB_VFS_LCHOWN(conn, smb_fname,
8325                                              set_owner, (gid_t)-1);
8326                 }
8327
8328                 if (ret != 0) {
8329                         status = map_nt_error_from_unix(errno);
8330                         return status;
8331                 }
8332         }
8333
8334         /*
8335          * Deal with the UNIX specific gid set.
8336          */
8337
8338         if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) &&
8339             (sbuf.st_ex_gid != set_grp)) {
8340                 int ret;
8341
8342                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
8343                           "changing group %u for file %s\n",
8344                           (unsigned int)set_grp,
8345                           smb_fname_str_dbg(smb_fname)));
8346                 if (fsp &&
8347                     !fsp->fsp_flags.is_pathref &&
8348                     fsp_get_io_fd(fsp) != -1)
8349                 {
8350                         ret = SMB_VFS_FCHOWN(fsp, (uid_t)-1, set_grp);
8351                 } else {
8352                         /*
8353                          * UNIX extensions calls must always operate
8354                          * on symlinks.
8355                          */
8356                         ret = SMB_VFS_LCHOWN(conn, smb_fname, (uid_t)-1,
8357                                   set_grp);
8358                 }
8359                 if (ret != 0) {
8360                         status = map_nt_error_from_unix(errno);
8361                         return status;
8362                 }
8363         }
8364
8365         /* Deal with any size changes. */
8366
8367         if (S_ISREG(sbuf.st_ex_mode)) {
8368                 status = smb_set_file_size(conn, req,
8369                                            fsp,
8370                                            smb_fname,
8371                                            &sbuf,
8372                                            size,
8373                                            false);
8374                 if (!NT_STATUS_IS_OK(status)) {
8375                         return status;
8376                 }
8377         }
8378
8379         /* Deal with any time changes. */
8380         if (is_omit_timespec(&ft.mtime) && is_omit_timespec(&ft.atime)) {
8381                 /* No change, don't cancel anything. */
8382                 return status;
8383         }
8384
8385         id = vfs_file_id_from_sbuf(conn, &sbuf);
8386         for(all_fsps = file_find_di_first(conn->sconn, id); all_fsps;
8387                         all_fsps = file_find_di_next(all_fsps)) {
8388                 /*
8389                  * We're setting the time explicitly for UNIX.
8390                  * Cancel any pending changes over all handles.
8391                  */
8392                 all_fsps->fsp_flags.update_write_time_on_close = false;
8393                 TALLOC_FREE(all_fsps->update_write_time_event);
8394         }
8395
8396         /*
8397          * Override the "setting_write_time"
8398          * parameter here as it almost does what
8399          * we need. Just remember if we modified
8400          * mtime and send the notify ourselves.
8401          */
8402         if (is_omit_timespec(&ft.mtime)) {
8403                 modify_mtime = false;
8404         }
8405
8406         status = smb_set_file_time(conn,
8407                                 fsp,
8408                                 smb_fname,
8409                                 &ft,
8410                                 false);
8411         if (modify_mtime) {
8412                 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
8413                         FILE_NOTIFY_CHANGE_LAST_WRITE, smb_fname->base_name);
8414         }
8415         return status;
8416 }
8417
8418 /****************************************************************************
8419  Deal with SMB_SET_FILE_UNIX_INFO2.
8420 ****************************************************************************/
8421
8422 static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
8423                                         struct smb_request *req,
8424                                         const char *pdata,
8425                                         int total_data,
8426                                         files_struct *fsp,
8427                                         const struct smb_filename *smb_fname)
8428 {
8429         NTSTATUS status;
8430         uint32_t smb_fflags;
8431         uint32_t smb_fmask;
8432
8433         if (total_data < 116) {
8434                 return NT_STATUS_INVALID_PARAMETER;
8435         }
8436
8437         /* Start by setting all the fields that are common between UNIX_BASIC
8438          * and UNIX_INFO2.
8439          */
8440         status = smb_set_file_unix_basic(conn, req, pdata, total_data,
8441                                          fsp, smb_fname);
8442         if (!NT_STATUS_IS_OK(status)) {
8443                 return status;
8444         }
8445
8446         smb_fflags = IVAL(pdata, 108);
8447         smb_fmask = IVAL(pdata, 112);
8448
8449         /* NB: We should only attempt to alter the file flags if the client
8450          * sends a non-zero mask.
8451          */
8452         if (smb_fmask != 0) {
8453                 int stat_fflags = 0;
8454
8455                 if (!map_info2_flags_to_sbuf(&smb_fname->st, smb_fflags,
8456                                              smb_fmask, &stat_fflags)) {
8457                         /* Client asked to alter a flag we don't understand. */
8458                         return NT_STATUS_INVALID_PARAMETER;
8459                 }
8460
8461                 if (fsp &&
8462                     !fsp->fsp_flags.is_pathref &&
8463                     fsp_get_io_fd(fsp) != -1)
8464                 {
8465                         /* XXX: we should be  using SMB_VFS_FCHFLAGS here. */
8466                         return NT_STATUS_NOT_SUPPORTED;
8467                 } else {
8468                         if (SMB_VFS_CHFLAGS(conn, smb_fname,
8469                                             stat_fflags) != 0) {
8470                                 return map_nt_error_from_unix(errno);
8471                         }
8472                 }
8473         }
8474
8475         /* XXX: need to add support for changing the create_time here. You
8476          * can do this for paths on Darwin with setattrlist(2). The right way
8477          * to hook this up is probably by extending the VFS utimes interface.
8478          */
8479
8480         return NT_STATUS_OK;
8481 }
8482
8483 /****************************************************************************
8484  Create a directory with POSIX semantics.
8485 ****************************************************************************/
8486
8487 static NTSTATUS smb_posix_mkdir(connection_struct *conn,
8488                                 struct smb_request *req,
8489                                 char **ppdata,
8490                                 int total_data,
8491                                 struct smb_filename *smb_fname,
8492                                 int *pdata_return_size)
8493 {
8494         NTSTATUS status = NT_STATUS_OK;
8495         uint32_t raw_unixmode = 0;
8496         mode_t unixmode = (mode_t)0;
8497         files_struct *fsp = NULL;
8498         uint16_t info_level_return = 0;
8499         int info;
8500         char *pdata = *ppdata;
8501         struct smb2_create_blobs *posx = NULL;
8502
8503         if (total_data < 18) {
8504                 return NT_STATUS_INVALID_PARAMETER;
8505         }
8506
8507         raw_unixmode = IVAL(pdata,8);
8508         /* Next 4 bytes are not yet defined. */
8509
8510         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8511                                       PERM_NEW_DIR, &unixmode);
8512         if (!NT_STATUS_IS_OK(status)) {
8513                 return status;
8514         }
8515
8516         status = make_smb2_posix_create_ctx(talloc_tos(), &posx, unixmode);
8517         if (!NT_STATUS_IS_OK(status)) {
8518                 DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
8519                             nt_errstr(status));
8520                 return status;
8521         }
8522
8523         DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
8524                   smb_fname_str_dbg(smb_fname), (unsigned int)unixmode));
8525
8526         status = SMB_VFS_CREATE_FILE(
8527                 conn,                                   /* conn */
8528                 req,                                    /* req */
8529                 smb_fname,                              /* fname */
8530                 FILE_READ_ATTRIBUTES,                   /* access_mask */
8531                 FILE_SHARE_NONE,                        /* share_access */
8532                 FILE_CREATE,                            /* create_disposition*/
8533                 FILE_DIRECTORY_FILE,                    /* create_options */
8534                 0,                                      /* file_attributes */
8535                 0,                                      /* oplock_request */
8536                 NULL,                                   /* lease */
8537                 0,                                      /* allocation_size */
8538                 0,                                      /* private_flags */
8539                 NULL,                                   /* sd */
8540                 NULL,                                   /* ea_list */
8541                 &fsp,                                   /* result */
8542                 &info,                                  /* pinfo */
8543                 posx,                                   /* in_context_blobs */
8544                 NULL);                                  /* out_context_blobs */
8545
8546         TALLOC_FREE(posx);
8547
8548         if (NT_STATUS_IS_OK(status)) {
8549                 close_file(req, fsp, NORMAL_CLOSE);
8550         }
8551
8552         info_level_return = SVAL(pdata,16);
8553  
8554         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
8555                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
8556         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
8557                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
8558         } else {
8559                 *pdata_return_size = 12;
8560         }
8561
8562         /* Realloc the data size */
8563         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
8564         if (*ppdata == NULL) {
8565                 *pdata_return_size = 0;
8566                 return NT_STATUS_NO_MEMORY;
8567         }
8568         pdata = *ppdata;
8569
8570         SSVAL(pdata,0,NO_OPLOCK_RETURN);
8571         SSVAL(pdata,2,0); /* No fnum. */
8572         SIVAL(pdata,4,info); /* Was directory created. */
8573
8574         switch (info_level_return) {
8575                 case SMB_QUERY_FILE_UNIX_BASIC:
8576                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
8577                         SSVAL(pdata,10,0); /* Padding. */
8578                         store_file_unix_basic(conn, pdata + 12, fsp,
8579                                               &smb_fname->st);
8580                         break;
8581                 case SMB_QUERY_FILE_UNIX_INFO2:
8582                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
8583                         SSVAL(pdata,10,0); /* Padding. */
8584                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
8585                                                     &smb_fname->st);
8586                         break;
8587                 default:
8588                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
8589                         SSVAL(pdata,10,0); /* Padding. */
8590                         break;
8591         }
8592
8593         return status;
8594 }
8595
8596 /****************************************************************************
8597  Open/Create a file with POSIX semantics.
8598 ****************************************************************************/
8599
8600 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
8601 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
8602
8603 static NTSTATUS smb_posix_open(connection_struct *conn,
8604                                struct smb_request *req,
8605                                 char **ppdata,
8606                                 int total_data,
8607                                 struct smb_filename *smb_fname,
8608                                 int *pdata_return_size)
8609 {
8610         bool extended_oplock_granted = False;
8611         char *pdata = *ppdata;
8612         uint32_t flags = 0;
8613         uint32_t wire_open_mode = 0;
8614         uint32_t raw_unixmode = 0;
8615         uint32_t attributes = 0;
8616         uint32_t create_disp = 0;
8617         uint32_t access_mask = 0;
8618         uint32_t create_options = FILE_NON_DIRECTORY_FILE;
8619         NTSTATUS status = NT_STATUS_OK;
8620         mode_t unixmode = (mode_t)0;
8621         files_struct *fsp = NULL;
8622         int oplock_request = 0;
8623         int info = 0;
8624         uint16_t info_level_return = 0;
8625         struct smb2_create_blobs *posx = NULL;
8626
8627         if (total_data < 18) {
8628                 return NT_STATUS_INVALID_PARAMETER;
8629         }
8630
8631         flags = IVAL(pdata,0);
8632         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
8633         if (oplock_request) {
8634                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
8635         }
8636
8637         wire_open_mode = IVAL(pdata,4);
8638
8639         if (wire_open_mode == (SMB_O_CREAT|SMB_O_DIRECTORY)) {
8640                 return smb_posix_mkdir(conn, req,
8641                                         ppdata,
8642                                         total_data,
8643                                         smb_fname,
8644                                         pdata_return_size);
8645         }
8646
8647         switch (wire_open_mode & SMB_ACCMODE) {
8648                 case SMB_O_RDONLY:
8649                         access_mask = SMB_O_RDONLY_MAPPING;
8650                         break;
8651                 case SMB_O_WRONLY:
8652                         access_mask = SMB_O_WRONLY_MAPPING;
8653                         break;
8654                 case SMB_O_RDWR:
8655                         access_mask = (SMB_O_RDONLY_MAPPING|
8656                                         SMB_O_WRONLY_MAPPING);
8657                         break;
8658                 default:
8659                         DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
8660                                 (unsigned int)wire_open_mode ));
8661                         return NT_STATUS_INVALID_PARAMETER;
8662         }
8663
8664         wire_open_mode &= ~SMB_ACCMODE;
8665
8666         /* First take care of O_CREAT|O_EXCL interactions. */
8667         switch (wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) {
8668                 case (SMB_O_CREAT | SMB_O_EXCL):
8669                         /* File exists fail. File not exist create. */
8670                         create_disp = FILE_CREATE;
8671                         break;
8672                 case SMB_O_CREAT:
8673                         /* File exists open. File not exist create. */
8674                         create_disp = FILE_OPEN_IF;
8675                         break;
8676                 case SMB_O_EXCL:
8677                         /* O_EXCL on its own without O_CREAT is undefined.
8678                            We deliberately ignore it as some versions of
8679                            Linux CIFSFS can send a bare O_EXCL on the
8680                            wire which other filesystems in the kernel
8681                            ignore. See bug 9519 for details. */
8682
8683                         /* Fallthrough. */
8684
8685                 case 0:
8686                         /* File exists open. File not exist fail. */
8687                         create_disp = FILE_OPEN;
8688                         break;
8689                 default:
8690                         DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
8691                                 (unsigned int)wire_open_mode ));
8692                         return NT_STATUS_INVALID_PARAMETER;
8693         }
8694
8695         /* Next factor in the effects of O_TRUNC. */
8696         wire_open_mode &= ~(SMB_O_CREAT | SMB_O_EXCL);
8697
8698         if (wire_open_mode & SMB_O_TRUNC) {
8699                 switch (create_disp) {
8700                         case FILE_CREATE:
8701                                 /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
8702                                 /* Leave create_disp alone as
8703                                    (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
8704                                 */
8705                                 /* File exists fail. File not exist create. */
8706                                 break;
8707                         case FILE_OPEN_IF:
8708                                 /* SMB_O_CREAT | SMB_O_TRUNC */
8709                                 /* File exists overwrite. File not exist create. */
8710                                 create_disp = FILE_OVERWRITE_IF;
8711                                 break;
8712                         case FILE_OPEN:
8713                                 /* SMB_O_TRUNC */
8714                                 /* File exists overwrite. File not exist fail. */
8715                                 create_disp = FILE_OVERWRITE;
8716                                 break;
8717                         default:
8718                                 /* Cannot get here. */
8719                                 smb_panic("smb_posix_open: logic error");
8720                                 return NT_STATUS_INVALID_PARAMETER;
8721                 }
8722         }
8723
8724         raw_unixmode = IVAL(pdata,8);
8725         /* Next 4 bytes are not yet defined. */
8726
8727         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8728                                       (VALID_STAT(smb_fname->st) ?
8729                                           PERM_EXISTING_FILE : PERM_NEW_FILE),
8730                                       &unixmode);
8731
8732         if (!NT_STATUS_IS_OK(status)) {
8733                 return status;
8734         }
8735
8736         status = make_smb2_posix_create_ctx(talloc_tos(), &posx, unixmode);
8737         if (!NT_STATUS_IS_OK(status)) {
8738                 DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
8739                             nt_errstr(status));
8740                 return status;
8741         }
8742
8743         if (wire_open_mode & SMB_O_SYNC) {
8744                 create_options |= FILE_WRITE_THROUGH;
8745         }
8746         if (wire_open_mode & SMB_O_APPEND) {
8747                 access_mask |= FILE_APPEND_DATA;
8748         }
8749         if (wire_open_mode & SMB_O_DIRECT) {
8750                 attributes |= FILE_FLAG_NO_BUFFERING;
8751         }
8752
8753         if ((wire_open_mode & SMB_O_DIRECTORY) ||
8754                         VALID_STAT_OF_DIR(smb_fname->st)) {
8755                 if (access_mask != SMB_O_RDONLY_MAPPING) {
8756                         return NT_STATUS_FILE_IS_A_DIRECTORY;
8757                 }
8758                 create_options &= ~FILE_NON_DIRECTORY_FILE;
8759                 create_options |= FILE_DIRECTORY_FILE;
8760         }
8761
8762         DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
8763                 smb_fname_str_dbg(smb_fname),
8764                 (unsigned int)wire_open_mode,
8765                 (unsigned int)unixmode ));
8766
8767         status = SMB_VFS_CREATE_FILE(
8768                 conn,                                   /* conn */
8769                 req,                                    /* req */
8770                 smb_fname,                              /* fname */
8771                 access_mask,                            /* access_mask */
8772                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
8773                     FILE_SHARE_DELETE),
8774                 create_disp,                            /* create_disposition*/
8775                 create_options,                         /* create_options */
8776                 attributes,                             /* file_attributes */
8777                 oplock_request,                         /* oplock_request */
8778                 NULL,                                   /* lease */
8779                 0,                                      /* allocation_size */
8780                 0,                                      /* private_flags */
8781                 NULL,                                   /* sd */
8782                 NULL,                                   /* ea_list */
8783                 &fsp,                                   /* result */
8784                 &info,                                  /* pinfo */
8785                 posx,                                   /* in_context_blobs */
8786                 NULL);                                  /* out_context_blobs */
8787
8788         TALLOC_FREE(posx);
8789
8790         if (!NT_STATUS_IS_OK(status)) {
8791                 return status;
8792         }
8793
8794         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
8795                 extended_oplock_granted = True;
8796         }
8797
8798         if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
8799                 extended_oplock_granted = True;
8800         }
8801
8802         info_level_return = SVAL(pdata,16);
8803  
8804         /* Allocate the correct return size. */
8805
8806         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
8807                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
8808         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
8809                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
8810         } else {
8811                 *pdata_return_size = 12;
8812         }
8813
8814         /* Realloc the data size */
8815         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
8816         if (*ppdata == NULL) {
8817                 close_file(req, fsp, ERROR_CLOSE);
8818                 *pdata_return_size = 0;
8819                 return NT_STATUS_NO_MEMORY;
8820         }
8821         pdata = *ppdata;
8822
8823         if (extended_oplock_granted) {
8824                 if (flags & REQUEST_BATCH_OPLOCK) {
8825                         SSVAL(pdata,0, BATCH_OPLOCK_RETURN);
8826                 } else {
8827                         SSVAL(pdata,0, EXCLUSIVE_OPLOCK_RETURN);
8828                 }
8829         } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
8830                 SSVAL(pdata,0, LEVEL_II_OPLOCK_RETURN);
8831         } else {
8832                 SSVAL(pdata,0,NO_OPLOCK_RETURN);
8833         }
8834
8835         SSVAL(pdata,2,fsp->fnum);
8836         SIVAL(pdata,4,info); /* Was file created etc. */
8837
8838         switch (info_level_return) {
8839                 case SMB_QUERY_FILE_UNIX_BASIC:
8840                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
8841                         SSVAL(pdata,10,0); /* padding. */
8842                         store_file_unix_basic(conn, pdata + 12, fsp,
8843                                               &smb_fname->st);
8844                         break;
8845                 case SMB_QUERY_FILE_UNIX_INFO2:
8846                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
8847                         SSVAL(pdata,10,0); /* padding. */
8848                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
8849                                                     &smb_fname->st);
8850                         break;
8851                 default:
8852                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
8853                         SSVAL(pdata,10,0); /* padding. */
8854                         break;
8855         }
8856         return NT_STATUS_OK;
8857 }
8858
8859 /****************************************************************************
8860  Delete a file with POSIX semantics.
8861 ****************************************************************************/
8862
8863 static NTSTATUS smb_posix_unlink(connection_struct *conn,
8864                                  struct smb_request *req,
8865                                 const char *pdata,
8866                                 int total_data,
8867                                 struct smb_filename *smb_fname)
8868 {
8869         NTSTATUS status = NT_STATUS_OK;
8870         files_struct *fsp = NULL;
8871         uint16_t flags = 0;
8872         char del = 1;
8873         int info = 0;
8874         int create_options = 0;
8875         struct share_mode_lock *lck = NULL;
8876         bool other_nonposix_opens;
8877         struct smb2_create_blobs *posx = NULL;
8878
8879         if (total_data < 2) {
8880                 return NT_STATUS_INVALID_PARAMETER;
8881         }
8882
8883         flags = SVAL(pdata,0);
8884
8885         if (!VALID_STAT(smb_fname->st)) {
8886                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
8887         }
8888
8889         if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
8890                         !VALID_STAT_OF_DIR(smb_fname->st)) {
8891                 return NT_STATUS_NOT_A_DIRECTORY;
8892         }
8893
8894         DEBUG(10,("smb_posix_unlink: %s %s\n",
8895                 (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
8896                 smb_fname_str_dbg(smb_fname)));
8897
8898         if (VALID_STAT_OF_DIR(smb_fname->st)) {
8899                 create_options |= FILE_DIRECTORY_FILE;
8900         }
8901
8902         status = make_smb2_posix_create_ctx(talloc_tos(), &posx, 0777);
8903         if (!NT_STATUS_IS_OK(status)) {
8904                 DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
8905                             nt_errstr(status));
8906                 return status;
8907         }
8908
8909         status = SMB_VFS_CREATE_FILE(
8910                 conn,                                   /* conn */
8911                 req,                                    /* req */
8912                 smb_fname,                              /* fname */
8913                 DELETE_ACCESS,                          /* access_mask */
8914                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
8915                     FILE_SHARE_DELETE),
8916                 FILE_OPEN,                              /* create_disposition*/
8917                 create_options,                         /* create_options */
8918                 0,                                      /* file_attributes */
8919                 0,                                      /* oplock_request */
8920                 NULL,                                   /* lease */
8921                 0,                                      /* allocation_size */
8922                 0,                                      /* private_flags */
8923                 NULL,                                   /* sd */
8924                 NULL,                                   /* ea_list */
8925                 &fsp,                                   /* result */
8926                 &info,                                  /* pinfo */
8927                 posx,                                   /* in_context_blobs */
8928                 NULL);                                  /* out_context_blobs */
8929
8930         TALLOC_FREE(posx);
8931
8932         if (!NT_STATUS_IS_OK(status)) {
8933                 return status;
8934         }
8935
8936         /*
8937          * Don't lie to client. If we can't really delete due to
8938          * non-POSIX opens return SHARING_VIOLATION.
8939          */
8940
8941         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
8942         if (lck == NULL) {
8943                 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
8944                           "lock for file %s\n", fsp_str_dbg(fsp)));
8945                 close_file(req, fsp, NORMAL_CLOSE);
8946                 return NT_STATUS_INVALID_PARAMETER;
8947         }
8948
8949         other_nonposix_opens = has_other_nonposix_opens(lck, fsp);
8950         if (other_nonposix_opens) {
8951                 /* Fail with sharing violation. */
8952                 TALLOC_FREE(lck);
8953                 close_file(req, fsp, NORMAL_CLOSE);
8954                 return NT_STATUS_SHARING_VIOLATION;
8955         }
8956
8957         /*
8958          * Set the delete on close.
8959          */
8960         status = smb_set_file_disposition_info(conn,
8961                                                 &del,
8962                                                 1,
8963                                                 fsp,
8964                                                 smb_fname);
8965
8966         TALLOC_FREE(lck);
8967
8968         if (!NT_STATUS_IS_OK(status)) {
8969                 close_file(req, fsp, NORMAL_CLOSE);
8970                 return status;
8971         }
8972         return close_file(req, fsp, NORMAL_CLOSE);
8973 }
8974
8975 static NTSTATUS smbd_do_posix_setfilepathinfo(struct connection_struct *conn,
8976                                               struct smb_request *req,
8977                                               TALLOC_CTX *mem_ctx,
8978                                               uint16_t info_level,
8979                                               struct smb_filename *smb_fname,
8980                                               files_struct *fsp,
8981                                               char **ppdata,
8982                                               int total_data,
8983                                               int *ret_data_size)
8984 {
8985         char *pdata = *ppdata;
8986         NTSTATUS status = NT_STATUS_OK;
8987         int data_return_size = 0;
8988
8989         *ret_data_size = 0;
8990
8991         if (!CAN_WRITE(conn)) {
8992                 /* Allow POSIX opens. The open path will deny
8993                  * any non-readonly opens. */
8994                 if (info_level != SMB_POSIX_PATH_OPEN) {
8995                         return NT_STATUS_DOS(ERRSRV, ERRaccess);
8996                 }
8997         }
8998
8999         DBG_DEBUG("file=%s (%s) info_level=%d totdata=%d\n",
9000                   smb_fname_str_dbg(smb_fname),
9001                   fsp_fnum_dbg(fsp),
9002                   info_level,
9003                   total_data);
9004
9005         switch (info_level) {
9006                 case SMB_SET_FILE_UNIX_BASIC:
9007                 {
9008                         status = smb_set_file_unix_basic(conn, req,
9009                                                         pdata,
9010                                                         total_data,
9011                                                         fsp,
9012                                                         smb_fname);
9013                         break;
9014                 }
9015
9016                 case SMB_SET_FILE_UNIX_INFO2:
9017                 {
9018                         status = smb_set_file_unix_info2(conn, req,
9019                                                         pdata,
9020                                                         total_data,
9021                                                         fsp,
9022                                                         smb_fname);
9023                         break;
9024                 }
9025
9026                 case SMB_SET_FILE_UNIX_LINK:
9027                 {
9028                         if (smb_fname == NULL) {
9029                                 /* We must have a pathname for this. */
9030                                 return NT_STATUS_INVALID_LEVEL;
9031                         }
9032                         status = smb_set_file_unix_link(conn, req, pdata,
9033                                                         total_data, smb_fname);
9034                         break;
9035                 }
9036
9037                 case SMB_SET_FILE_UNIX_HLINK:
9038                 {
9039                         if (smb_fname == NULL) {
9040                                 /* We must have a pathname for this. */
9041                                 return NT_STATUS_INVALID_LEVEL;
9042                         }
9043                         status = smb_set_file_unix_hlink(conn, req,
9044                                                          pdata, total_data,
9045                                                          smb_fname);
9046                         break;
9047                 }
9048
9049 #if defined(HAVE_POSIX_ACLS)
9050                 case SMB_SET_POSIX_ACL:
9051                 {
9052                         status = smb_set_posix_acl(conn,
9053                                                 req,
9054                                                 pdata,
9055                                                 total_data,
9056                                                 fsp,
9057                                                 smb_fname);
9058                         break;
9059                 }
9060 #endif
9061
9062                 case SMB_SET_POSIX_LOCK:
9063                 {
9064                         if (fsp == NULL) {
9065                                 return NT_STATUS_INVALID_LEVEL;
9066                         }
9067                         status = smb_set_posix_lock(conn, req,
9068                                                     pdata, total_data, fsp);
9069                         break;
9070                 }
9071
9072                 case SMB_POSIX_PATH_OPEN:
9073                 {
9074                         if (smb_fname == NULL) {
9075                                 /* We must have a pathname for this. */
9076                                 return NT_STATUS_INVALID_LEVEL;
9077                         }
9078
9079                         status = smb_posix_open(conn, req,
9080                                                 ppdata,
9081                                                 total_data,
9082                                                 smb_fname,
9083                                                 &data_return_size);
9084                         break;
9085                 }
9086
9087                 case SMB_POSIX_PATH_UNLINK:
9088                 {
9089                         if (smb_fname == NULL) {
9090                                 /* We must have a pathname for this. */
9091                                 return NT_STATUS_INVALID_LEVEL;
9092                         }
9093
9094                         status = smb_posix_unlink(conn, req,
9095                                                 pdata,
9096                                                 total_data,
9097                                                 smb_fname);
9098                         break;
9099                 }
9100
9101                 default:
9102                         return NT_STATUS_INVALID_LEVEL;
9103         }
9104
9105         if (!NT_STATUS_IS_OK(status)) {
9106                 return status;
9107         }
9108
9109         *ret_data_size = data_return_size;
9110         return NT_STATUS_OK;
9111 }
9112
9113 NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
9114                                 struct smb_request *req,
9115                                 TALLOC_CTX *mem_ctx,
9116                                 uint16_t info_level,
9117                                 files_struct *fsp,
9118                                 struct smb_filename *smb_fname,
9119                                 char **ppdata, int total_data,
9120                                 int *ret_data_size)
9121 {
9122         char *pdata = *ppdata;
9123         NTSTATUS status = NT_STATUS_OK;
9124         int data_return_size = 0;
9125
9126         if (INFO_LEVEL_IS_UNIX(info_level)) {
9127                 if (!lp_unix_extensions()) {
9128                         return NT_STATUS_INVALID_LEVEL;
9129                 }
9130
9131                 status = smbd_do_posix_setfilepathinfo(conn,
9132                                                        req,
9133                                                        req,
9134                                                        info_level,
9135                                                        smb_fname,
9136                                                        fsp,
9137                                                        ppdata,
9138                                                        total_data,
9139                                                        &data_return_size);
9140                 if (!NT_STATUS_IS_OK(status)) {
9141                         return status;
9142                 }
9143                 *ret_data_size = data_return_size;
9144                 return NT_STATUS_OK;
9145         }
9146
9147         *ret_data_size = 0;
9148
9149         DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "
9150                  "totdata=%d\n", smb_fname_str_dbg(smb_fname),
9151                  fsp_fnum_dbg(fsp),
9152                  info_level, total_data));
9153
9154         switch (info_level) {
9155
9156                 case SMB_INFO_STANDARD:
9157                 {
9158                         status = smb_set_info_standard(conn,
9159                                         pdata,
9160                                         total_data,
9161                                         fsp,
9162                                         smb_fname);
9163                         break;
9164                 }
9165
9166                 case SMB_INFO_SET_EA:
9167                 {
9168                         status = smb_info_set_ea(conn,
9169                                                 pdata,
9170                                                 total_data,
9171                                                 fsp,
9172                                                 smb_fname);
9173                         break;
9174                 }
9175
9176                 case SMB_SET_FILE_BASIC_INFO:
9177                 case SMB_FILE_BASIC_INFORMATION:
9178                 {
9179                         status = smb_set_file_basic_info(conn,
9180                                                         pdata,
9181                                                         total_data,
9182                                                         fsp,
9183                                                         smb_fname);
9184                         break;
9185                 }
9186
9187                 case SMB_FILE_ALLOCATION_INFORMATION:
9188                 case SMB_SET_FILE_ALLOCATION_INFO:
9189                 {
9190                         status = smb_set_file_allocation_info(conn, req,
9191                                                                 pdata,
9192                                                                 total_data,
9193                                                                 fsp,
9194                                                                 smb_fname);
9195                         break;
9196                 }
9197
9198                 case SMB_FILE_END_OF_FILE_INFORMATION:
9199                 case SMB_SET_FILE_END_OF_FILE_INFO:
9200                 {
9201                         /*
9202                          * XP/Win7 both fail after the createfile with
9203                          * SMB_SET_FILE_END_OF_FILE_INFO but not
9204                          * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
9205                          * The level is known here, so pass it down
9206                          * appropriately.
9207                          */
9208                         bool should_fail =
9209                             (info_level == SMB_SET_FILE_END_OF_FILE_INFO);
9210
9211                         status = smb_set_file_end_of_file_info(conn, req,
9212                                                                 pdata,
9213                                                                 total_data,
9214                                                                 fsp,
9215                                                                 smb_fname,
9216                                                                 should_fail);
9217                         break;
9218                 }
9219
9220                 case SMB_FILE_DISPOSITION_INFORMATION:
9221                 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
9222                 {
9223 #if 0
9224                         /* JRA - We used to just ignore this on a path ? 
9225                          * Shouldn't this be invalid level on a pathname
9226                          * based call ?
9227                          */
9228                         if (tran_call != TRANSACT2_SETFILEINFO) {
9229                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
9230                         }
9231 #endif
9232                         status = smb_set_file_disposition_info(conn,
9233                                                 pdata,
9234                                                 total_data,
9235                                                 fsp,
9236                                                 smb_fname);
9237                         break;
9238                 }
9239
9240                 case SMB_FILE_POSITION_INFORMATION:
9241                 {
9242                         status = smb_file_position_information(conn,
9243                                                 pdata,
9244                                                 total_data,
9245                                                 fsp);
9246                         break;
9247                 }
9248
9249                 case SMB_FILE_FULL_EA_INFORMATION:
9250                 {
9251                         status = smb_set_file_full_ea_info(conn,
9252                                                 pdata,
9253                                                 total_data,
9254                                                 fsp);
9255                         break;
9256                 }
9257
9258                 /* From tridge Samba4 : 
9259                  * MODE_INFORMATION in setfileinfo (I have no
9260                  * idea what "mode information" on a file is - it takes a value of 0,
9261                  * 2, 4 or 6. What could it be?).
9262                  */
9263
9264                 case SMB_FILE_MODE_INFORMATION:
9265                 {
9266                         status = smb_file_mode_information(conn,
9267                                                 pdata,
9268                                                 total_data);
9269                         break;
9270                 }
9271
9272                 /* [MS-SMB2] 3.3.5.21.1 states we MUST fail with STATUS_NOT_SUPPORTED. */
9273                 case SMB_FILE_VALID_DATA_LENGTH_INFORMATION:
9274                 case SMB_FILE_SHORT_NAME_INFORMATION:
9275                         return NT_STATUS_NOT_SUPPORTED;
9276
9277                 case SMB_FILE_RENAME_INFORMATION:
9278                 {
9279                         status = smb_file_rename_information(conn, req,
9280                                                              pdata, total_data,
9281                                                              fsp, smb_fname);
9282                         break;
9283                 }
9284
9285                 case SMB2_FILE_RENAME_INFORMATION_INTERNAL:
9286                 {
9287                         /* SMB2 rename information. */
9288                         status = smb2_file_rename_information(conn, req,
9289                                                              pdata, total_data,
9290                                                              fsp, smb_fname);
9291                         break;
9292                 }
9293
9294                 case SMB_FILE_LINK_INFORMATION:
9295                 {
9296                         status = smb_file_link_information(conn, req,
9297                                                         pdata, total_data,
9298                                                         fsp, smb_fname);
9299                         break;
9300                 }
9301
9302                 default:
9303                         return NT_STATUS_INVALID_LEVEL;
9304         }
9305
9306         if (!NT_STATUS_IS_OK(status)) {
9307                 return status;
9308         }
9309
9310         *ret_data_size = data_return_size;
9311         return NT_STATUS_OK;
9312 }
9313
9314 /****************************************************************************
9315  Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
9316 ****************************************************************************/
9317
9318 static void call_trans2setfilepathinfo(connection_struct *conn,
9319                                        struct smb_request *req,
9320                                        unsigned int tran_call,
9321                                        char **pparams, int total_params,
9322                                        char **ppdata, int total_data,
9323                                        unsigned int max_data_bytes)
9324 {
9325         char *params = *pparams;
9326         char *pdata = *ppdata;
9327         uint16_t info_level;
9328         struct smb_filename *smb_fname = NULL;
9329         files_struct *fsp = NULL;
9330         NTSTATUS status = NT_STATUS_OK;
9331         int data_return_size = 0;
9332
9333         if (!params) {
9334                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9335                 return;
9336         }
9337
9338         if (tran_call == TRANSACT2_SETFILEINFO) {
9339                 if (total_params < 4) {
9340                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9341                         return;
9342                 }
9343
9344                 fsp = file_fsp(req, SVAL(params,0));
9345                 /* Basic check for non-null fsp. */
9346                 if (!check_fsp_open(conn, req, fsp)) {
9347                         return;
9348                 }
9349                 info_level = SVAL(params,2);
9350
9351                 smb_fname = fsp->fsp_name;
9352
9353                 if (fsp_get_pathref_fd(fsp) == -1) {
9354                         /*
9355                          * This is actually a SETFILEINFO on a directory
9356                          * handle (returned from an NT SMB). NT5.0 seems
9357                          * to do this call. JRA.
9358                          */
9359                         if (INFO_LEVEL_IS_UNIX(info_level)) {
9360                                 /* Always do lstat for UNIX calls. */
9361                                 if (SMB_VFS_LSTAT(conn, smb_fname)) {
9362                                         DEBUG(3,("call_trans2setfilepathinfo: "
9363                                                  "SMB_VFS_LSTAT of %s failed "
9364                                                  "(%s)\n",
9365                                                  smb_fname_str_dbg(smb_fname),
9366                                                  strerror(errno)));
9367                                         reply_nterror(req, map_nt_error_from_unix(errno));
9368                                         return;
9369                                 }
9370                         } else {
9371                                 if (SMB_VFS_STAT(conn, smb_fname) != 0) {
9372                                         DEBUG(3,("call_trans2setfilepathinfo: "
9373                                                  "fileinfo of %s failed (%s)\n",
9374                                                  smb_fname_str_dbg(smb_fname),
9375                                                  strerror(errno)));
9376                                         reply_nterror(req, map_nt_error_from_unix(errno));
9377                                         return;
9378                                 }
9379                         }
9380                 } else if (fsp->print_file) {
9381                         /*
9382                          * Doing a DELETE_ON_CLOSE should cancel a print job.
9383                          */
9384                         if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
9385                                 fsp->fh->private_options |= NTCREATEX_FLAG_DELETE_ON_CLOSE;
9386
9387                                 DEBUG(3,("call_trans2setfilepathinfo: "
9388                                          "Cancelling print job (%s)\n",
9389                                          fsp_str_dbg(fsp)));
9390
9391                                 SSVAL(params,0,0);
9392                                 send_trans2_replies(conn, req, NT_STATUS_OK, params, 2,
9393                                                     *ppdata, 0,
9394                                                     max_data_bytes);
9395                                 return;
9396                         } else {
9397                                 reply_nterror(req,
9398                                         NT_STATUS_OBJECT_PATH_NOT_FOUND);
9399                                 return;
9400                         }
9401                 } else {
9402                         /*
9403                          * Original code - this is an open file.
9404                          */
9405                         if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
9406                                 DEBUG(3,("call_trans2setfilepathinfo: fstat "
9407                                          "of %s failed (%s)\n", fsp_fnum_dbg(fsp),
9408                                          strerror(errno)));
9409                                 reply_nterror(req, map_nt_error_from_unix(errno));
9410                                 return;
9411                         }
9412                 }
9413         } else {
9414                 char *fname = NULL;
9415                 uint32_t ucf_flags = ucf_flags_from_smb_request(req);
9416
9417                 /* set path info */
9418                 if (total_params < 7) {
9419                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9420                         return;
9421                 }
9422
9423                 info_level = SVAL(params,0);
9424                 if (req->posix_pathnames) {
9425                         srvstr_get_path_posix(req,
9426                                 params,
9427                                 req->flags2,
9428                                 &fname,
9429                                 &params[6],
9430                                 total_params - 6,
9431                                 STR_TERMINATE,
9432                                 &status);
9433                 } else {
9434                         srvstr_get_path(req,
9435                                 params,
9436                                 req->flags2,
9437                                 &fname,
9438                                 &params[6],
9439                                 total_params - 6,
9440                                 STR_TERMINATE,
9441                                 &status);
9442                 }
9443                 if (!NT_STATUS_IS_OK(status)) {
9444                         reply_nterror(req, status);
9445                         return;
9446                 }
9447
9448                 status = filename_convert(req, conn,
9449                                          fname,
9450                                          ucf_flags,
9451                                          0,
9452                                          &smb_fname);
9453                 if (!NT_STATUS_IS_OK(status)) {
9454                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
9455                                 reply_botherror(req,
9456                                                 NT_STATUS_PATH_NOT_COVERED,
9457                                                 ERRSRV, ERRbadpath);
9458                                 return;
9459                         }
9460                         reply_nterror(req, status);
9461                         return;
9462                 }
9463
9464                 if (INFO_LEVEL_IS_UNIX(info_level)) {
9465                         /*
9466                          * For CIFS UNIX extensions the target name may not exist.
9467                          */
9468
9469                         /* Always do lstat for UNIX calls. */
9470                         SMB_VFS_LSTAT(conn, smb_fname);
9471
9472                 } else if (!VALID_STAT(smb_fname->st) &&
9473                            SMB_VFS_STAT(conn, smb_fname)) {
9474                         DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
9475                                  "%s failed (%s)\n",
9476                                  smb_fname_str_dbg(smb_fname),
9477                                  strerror(errno)));
9478                         reply_nterror(req, map_nt_error_from_unix(errno));
9479                         return;
9480                 }
9481         }
9482
9483         DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
9484                  "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
9485                  fsp_fnum_dbg(fsp),
9486                  info_level,total_data));
9487
9488         /* Realloc the parameter size */
9489         *pparams = (char *)SMB_REALLOC(*pparams,2);
9490         if (*pparams == NULL) {
9491                 reply_nterror(req, NT_STATUS_NO_MEMORY);
9492                 return;
9493         }
9494         params = *pparams;
9495
9496         SSVAL(params,0,0);
9497
9498         status = smbd_do_setfilepathinfo(conn, req, req,
9499                                          info_level,
9500                                          fsp,
9501                                          smb_fname,
9502                                          ppdata, total_data,
9503                                          &data_return_size);
9504         if (!NT_STATUS_IS_OK(status)) {
9505                 if (open_was_deferred(req->xconn, req->mid)) {
9506                         /* We have re-scheduled this call. */
9507                         return;
9508                 }
9509                 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
9510                         bool ok = defer_smb1_sharing_violation(req);
9511                         if (ok) {
9512                                 return;
9513                         }
9514                 }
9515                 if (NT_STATUS_EQUAL(status, NT_STATUS_EVENT_PENDING)) {
9516                         /* We have re-scheduled this call. */
9517                         return;
9518                 }
9519                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
9520                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
9521                                         ERRSRV, ERRbadpath);
9522                         return;
9523                 }
9524                 if (info_level == SMB_POSIX_PATH_OPEN) {
9525                         reply_openerror(req, status);
9526                         return;
9527                 }
9528
9529                 /*
9530                  * Invalid EA name needs to return 2 param bytes,
9531                  * not a zero-length error packet.
9532                  */
9533                 if (NT_STATUS_EQUAL(status, STATUS_INVALID_EA_NAME)) {
9534                         send_trans2_replies(conn, req, status, params, 2, NULL, 0,
9535                                         max_data_bytes);
9536                 } else {
9537                         reply_nterror(req, status);
9538                 }
9539                 return;
9540         }
9541
9542         send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, data_return_size,
9543                             max_data_bytes);
9544
9545         return;
9546 }
9547
9548 /****************************************************************************
9549  Reply to a TRANS2_MKDIR (make directory with extended attributes).
9550 ****************************************************************************/
9551
9552 static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
9553                              char **pparams, int total_params,
9554                              char **ppdata, int total_data,
9555                              unsigned int max_data_bytes)
9556 {
9557         struct smb_filename *smb_dname = NULL;
9558         char *params = *pparams;
9559         char *pdata = *ppdata;
9560         char *directory = NULL;
9561         NTSTATUS status = NT_STATUS_OK;
9562         struct ea_list *ea_list = NULL;
9563         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
9564         TALLOC_CTX *ctx = talloc_tos();
9565
9566         if (!CAN_WRITE(conn)) {
9567                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9568                 return;
9569         }
9570
9571         if (total_params < 5) {
9572                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9573                 return;
9574         }
9575
9576         if (req->posix_pathnames) {
9577                 srvstr_get_path_posix(ctx,
9578                         params,
9579                         req->flags2,
9580                         &directory,
9581                         &params[4],
9582                         total_params - 4,
9583                         STR_TERMINATE,
9584                         &status);
9585         } else {
9586                 srvstr_get_path(ctx,
9587                         params,
9588                         req->flags2,
9589                         &directory,
9590                         &params[4],
9591                         total_params - 4,
9592                         STR_TERMINATE,
9593                         &status);
9594         }
9595         if (!NT_STATUS_IS_OK(status)) {
9596                 reply_nterror(req, status);
9597                 return;
9598         }
9599
9600         DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
9601
9602         status = filename_convert(ctx,
9603                                 conn,
9604                                 directory,
9605                                 ucf_flags,
9606                                 0,
9607                                 &smb_dname);
9608
9609         if (!NT_STATUS_IS_OK(status)) {
9610                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
9611                         reply_botherror(req,
9612                                 NT_STATUS_PATH_NOT_COVERED,
9613                                 ERRSRV, ERRbadpath);
9614                         return;
9615                 }
9616                 reply_nterror(req, status);
9617                 return;
9618         }
9619
9620         /*
9621          * OS/2 workplace shell seems to send SET_EA requests of "null"
9622          * length (4 bytes containing IVAL 4).
9623          * They seem to have no effect. Bug #3212. JRA.
9624          */
9625
9626         if (total_data && (total_data != 4)) {
9627                 /* Any data in this call is an EA list. */
9628                 if (total_data < 10) {
9629                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9630                         goto out;
9631                 }
9632
9633                 if (IVAL(pdata,0) > total_data) {
9634                         DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
9635                                 IVAL(pdata,0), (unsigned int)total_data));
9636                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9637                         goto out;
9638                 }
9639
9640                 ea_list = read_ea_list(talloc_tos(), pdata + 4,
9641                                        total_data - 4);
9642                 if (!ea_list) {
9643                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9644                         goto out;
9645                 }
9646
9647                 if (!lp_ea_support(SNUM(conn))) {
9648                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
9649                         goto out;
9650                 }
9651         }
9652         /* If total_data == 4 Windows doesn't care what values
9653          * are placed in that field, it just ignores them.
9654          * The System i QNTC IBM SMB client puts bad values here,
9655          * so ignore them. */
9656
9657         status = create_directory(conn, req, smb_dname);
9658
9659         if (!NT_STATUS_IS_OK(status)) {
9660                 reply_nterror(req, status);
9661                 goto out;
9662         }
9663
9664         /* Try and set any given EA. */
9665         if (ea_list) {
9666                 status = set_ea(conn, NULL, smb_dname, ea_list);
9667                 if (!NT_STATUS_IS_OK(status)) {
9668                         reply_nterror(req, status);
9669                         goto out;
9670                 }
9671         }
9672
9673         /* Realloc the parameter and data sizes */
9674         *pparams = (char *)SMB_REALLOC(*pparams,2);
9675         if(*pparams == NULL) {
9676                 reply_nterror(req, NT_STATUS_NO_MEMORY);
9677                 goto out;
9678         }
9679         params = *pparams;
9680
9681         SSVAL(params,0,0);
9682
9683         send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, 0, max_data_bytes);
9684
9685  out:
9686         TALLOC_FREE(smb_dname);
9687         return;
9688 }
9689
9690 /****************************************************************************
9691  Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
9692  We don't actually do this - we just send a null response.
9693 ****************************************************************************/
9694
9695 static void call_trans2findnotifyfirst(connection_struct *conn,
9696                                        struct smb_request *req,
9697                                        char **pparams, int total_params,
9698                                        char **ppdata, int total_data,
9699                                        unsigned int max_data_bytes)
9700 {
9701         char *params = *pparams;
9702         uint16_t info_level;
9703
9704         if (total_params < 6) {
9705                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9706                 return;
9707         }
9708
9709         info_level = SVAL(params,4);
9710         DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
9711
9712         switch (info_level) {
9713                 case 1:
9714                 case 2:
9715                         break;
9716                 default:
9717                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
9718                         return;
9719         }
9720
9721         /* Realloc the parameter and data sizes */
9722         *pparams = (char *)SMB_REALLOC(*pparams,6);
9723         if (*pparams == NULL) {
9724                 reply_nterror(req, NT_STATUS_NO_MEMORY);
9725                 return;
9726         }
9727         params = *pparams;
9728
9729         SSVAL(params,0,fnf_handle);
9730         SSVAL(params,2,0); /* No changes */
9731         SSVAL(params,4,0); /* No EA errors */
9732
9733         fnf_handle++;
9734
9735         if(fnf_handle == 0)
9736                 fnf_handle = 257;
9737
9738         send_trans2_replies(conn, req, NT_STATUS_OK, params, 6, *ppdata, 0, max_data_bytes);
9739
9740         return;
9741 }
9742
9743 /****************************************************************************
9744  Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for 
9745  changes). Currently this does nothing.
9746 ****************************************************************************/
9747
9748 static void call_trans2findnotifynext(connection_struct *conn,
9749                                       struct smb_request *req,
9750                                       char **pparams, int total_params,
9751                                       char **ppdata, int total_data,
9752                                       unsigned int max_data_bytes)
9753 {
9754         char *params = *pparams;
9755
9756         DEBUG(3,("call_trans2findnotifynext\n"));
9757
9758         /* Realloc the parameter and data sizes */
9759         *pparams = (char *)SMB_REALLOC(*pparams,4);
9760         if (*pparams == NULL) {
9761                 reply_nterror(req, NT_STATUS_NO_MEMORY);
9762                 return;
9763         }
9764         params = *pparams;
9765
9766         SSVAL(params,0,0); /* No changes */
9767         SSVAL(params,2,0); /* No EA errors */
9768
9769         send_trans2_replies(conn, req, NT_STATUS_OK, params, 4, *ppdata, 0, max_data_bytes);
9770
9771         return;
9772 }
9773
9774 /****************************************************************************
9775  Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
9776 ****************************************************************************/
9777
9778 static void call_trans2getdfsreferral(connection_struct *conn,
9779                                       struct smb_request *req,
9780                                       char **pparams, int total_params,
9781                                       char **ppdata, int total_data,
9782                                       unsigned int max_data_bytes)
9783 {
9784         char *params = *pparams;
9785         char *pathname = NULL;
9786         int reply_size = 0;
9787         int max_referral_level;
9788         NTSTATUS status = NT_STATUS_OK;
9789         TALLOC_CTX *ctx = talloc_tos();
9790
9791         DEBUG(10,("call_trans2getdfsreferral\n"));
9792
9793         if (total_params < 3) {
9794                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9795                 return;
9796         }
9797
9798         max_referral_level = SVAL(params,0);
9799
9800         if(!lp_host_msdfs()) {
9801                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
9802                 return;
9803         }
9804
9805         srvstr_pull_talloc(ctx, params, req->flags2, &pathname, &params[2],
9806                     total_params - 2, STR_TERMINATE);
9807         if (!pathname) {
9808                 reply_nterror(req, NT_STATUS_NOT_FOUND);
9809                 return;
9810         }
9811         if((reply_size = setup_dfs_referral(conn, pathname, max_referral_level,
9812                                             ppdata,&status)) < 0) {
9813                 reply_nterror(req, status);
9814                 return;
9815         }
9816
9817         SSVAL((discard_const_p(uint8_t, req->inbuf)), smb_flg2,
9818               SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
9819         send_trans2_replies(conn, req, NT_STATUS_OK, 0,0,*ppdata,reply_size, max_data_bytes);
9820
9821         return;
9822 }
9823
9824 #define LMCAT_SPL       0x53
9825 #define LMFUNC_GETJOBID 0x60
9826
9827 /****************************************************************************
9828  Reply to a TRANS2_IOCTL - used for OS/2 printing.
9829 ****************************************************************************/
9830
9831 static void call_trans2ioctl(connection_struct *conn,
9832                              struct smb_request *req,
9833                              char **pparams, int total_params,
9834                              char **ppdata, int total_data,
9835                              unsigned int max_data_bytes)
9836 {
9837         const struct loadparm_substitution *lp_sub =
9838                 loadparm_s3_global_substitution();
9839         char *pdata = *ppdata;
9840         files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0));
9841         NTSTATUS status;
9842         size_t len = 0;
9843
9844         /* check for an invalid fid before proceeding */
9845
9846         if (!fsp) {
9847                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
9848                 return;
9849         }
9850
9851         if ((SVAL(req->vwv+16, 0) == LMCAT_SPL)
9852             && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
9853                 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
9854                 if (*ppdata == NULL) {
9855                         reply_nterror(req, NT_STATUS_NO_MEMORY);
9856                         return;
9857                 }
9858                 pdata = *ppdata;
9859
9860                 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
9861                         CAN ACCEPT THIS IN UNICODE. JRA. */
9862
9863                 /* Job number */
9864                 SSVAL(pdata, 0, print_spool_rap_jobid(fsp->print_file));
9865
9866                 status = srvstr_push(pdata, req->flags2, pdata + 2,
9867                             lp_netbios_name(), 15,
9868                             STR_ASCII|STR_TERMINATE, &len); /* Our NetBIOS name */
9869                 if (!NT_STATUS_IS_OK(status)) {
9870                         reply_nterror(req, status);
9871                         return;
9872                 }
9873                 status = srvstr_push(pdata, req->flags2, pdata+18,
9874                             lp_servicename(talloc_tos(), lp_sub, SNUM(conn)), 13,
9875                             STR_ASCII|STR_TERMINATE, &len); /* Service name */
9876                 if (!NT_STATUS_IS_OK(status)) {
9877                         reply_nterror(req, status);
9878                         return;
9879                 }
9880                 send_trans2_replies(conn, req, NT_STATUS_OK, *pparams, 0, *ppdata, 32,
9881                                     max_data_bytes);
9882                 return;
9883         }
9884
9885         DEBUG(2,("Unknown TRANS2_IOCTL\n"));
9886         reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
9887 }
9888
9889 /****************************************************************************
9890  Reply to a SMBfindclose (stop trans2 directory search).
9891 ****************************************************************************/
9892
9893 void reply_findclose(struct smb_request *req)
9894 {
9895         int dptr_num;
9896         struct smbd_server_connection *sconn = req->sconn;
9897         files_struct *fsp = NULL;
9898
9899         START_PROFILE(SMBfindclose);
9900
9901         if (req->wct < 1) {
9902                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9903                 END_PROFILE(SMBfindclose);
9904                 return;
9905         }
9906
9907         dptr_num = SVALS(req->vwv+0, 0);
9908
9909         DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
9910
9911         /*
9912          * OS/2 seems to use -1 to indicate "close all directories"
9913          * This has to mean on this specific connection struct.
9914          */
9915         if (dptr_num == -1) {
9916                 dptr_closecnum(req->conn);
9917         } else {
9918                 fsp = dptr_fetch_lanman2_fsp(sconn, dptr_num);
9919                 dptr_num = -1;
9920                 if (fsp != NULL) {
9921                         close_file(NULL, fsp, NORMAL_CLOSE);
9922                         fsp = NULL;
9923                 }
9924         }
9925
9926         reply_outbuf(req, 0, 0);
9927
9928         DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
9929
9930         END_PROFILE(SMBfindclose);
9931         return;
9932 }
9933
9934 /****************************************************************************
9935  Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
9936 ****************************************************************************/
9937
9938 void reply_findnclose(struct smb_request *req)
9939 {
9940         int dptr_num;
9941
9942         START_PROFILE(SMBfindnclose);
9943
9944         if (req->wct < 1) {
9945                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9946                 END_PROFILE(SMBfindnclose);
9947                 return;
9948         }
9949
9950         dptr_num = SVAL(req->vwv+0, 0);
9951
9952         DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
9953
9954         /* We never give out valid handles for a 
9955            findnotifyfirst - so any dptr_num is ok here. 
9956            Just ignore it. */
9957
9958         reply_outbuf(req, 0, 0);
9959
9960         DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
9961
9962         END_PROFILE(SMBfindnclose);
9963         return;
9964 }
9965
9966 static void handle_trans2(connection_struct *conn, struct smb_request *req,
9967                           struct trans_state *state)
9968 {
9969         if (get_Protocol() >= PROTOCOL_NT1) {
9970                 req->flags2 |= 0x40; /* IS_LONG_NAME */
9971                 SSVAL((discard_const_p(uint8_t, req->inbuf)),smb_flg2,req->flags2);
9972         }
9973
9974         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
9975                 if (state->call != TRANSACT2_QFSINFO &&
9976                     state->call != TRANSACT2_SETFSINFO) {
9977                         DEBUG(0,("handle_trans2: encryption required "
9978                                 "with call 0x%x\n",
9979                                 (unsigned int)state->call));
9980                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9981                         return;
9982                 }
9983         }
9984
9985         SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
9986
9987         /* Now we must call the relevant TRANS2 function */
9988         switch(state->call)  {
9989         case TRANSACT2_OPEN:
9990         {
9991                 START_PROFILE(Trans2_open);
9992                 call_trans2open(conn, req,
9993                                 &state->param, state->total_param,
9994                                 &state->data, state->total_data,
9995                                 state->max_data_return);
9996                 END_PROFILE(Trans2_open);
9997                 break;
9998         }
9999
10000         case TRANSACT2_FINDFIRST:
10001         {
10002                 START_PROFILE(Trans2_findfirst);
10003                 call_trans2findfirst(conn, req,
10004                                      &state->param, state->total_param,
10005                                      &state->data, state->total_data,
10006                                      state->max_data_return);
10007                 END_PROFILE(Trans2_findfirst);
10008                 break;
10009         }
10010
10011         case TRANSACT2_FINDNEXT:
10012         {
10013                 START_PROFILE(Trans2_findnext);
10014                 call_trans2findnext(conn, req,
10015                                     &state->param, state->total_param,
10016                                     &state->data, state->total_data,
10017                                     state->max_data_return);
10018                 END_PROFILE(Trans2_findnext);
10019                 break;
10020         }
10021
10022         case TRANSACT2_QFSINFO:
10023         {
10024                 START_PROFILE(Trans2_qfsinfo);
10025                 call_trans2qfsinfo(conn, req,
10026                                    &state->param, state->total_param,
10027                                    &state->data, state->total_data,
10028                                    state->max_data_return);
10029                 END_PROFILE(Trans2_qfsinfo);
10030             break;
10031         }
10032
10033         case TRANSACT2_SETFSINFO:
10034         {
10035                 START_PROFILE(Trans2_setfsinfo);
10036                 call_trans2setfsinfo(conn, req,
10037                                      &state->param, state->total_param,
10038                                      &state->data, state->total_data,
10039                                      state->max_data_return);
10040                 END_PROFILE(Trans2_setfsinfo);
10041                 break;
10042         }
10043
10044         case TRANSACT2_QPATHINFO:
10045         case TRANSACT2_QFILEINFO:
10046         {
10047                 START_PROFILE(Trans2_qpathinfo);
10048                 call_trans2qfilepathinfo(conn, req, state->call,
10049                                          &state->param, state->total_param,
10050                                          &state->data, state->total_data,
10051                                          state->max_data_return);
10052                 END_PROFILE(Trans2_qpathinfo);
10053                 break;
10054         }
10055
10056         case TRANSACT2_SETPATHINFO:
10057         case TRANSACT2_SETFILEINFO:
10058         {
10059                 START_PROFILE(Trans2_setpathinfo);
10060                 call_trans2setfilepathinfo(conn, req, state->call,
10061                                            &state->param, state->total_param,
10062                                            &state->data, state->total_data,
10063                                            state->max_data_return);
10064                 END_PROFILE(Trans2_setpathinfo);
10065                 break;
10066         }
10067
10068         case TRANSACT2_FINDNOTIFYFIRST:
10069         {
10070                 START_PROFILE(Trans2_findnotifyfirst);
10071                 call_trans2findnotifyfirst(conn, req,
10072                                            &state->param, state->total_param,
10073                                            &state->data, state->total_data,
10074                                            state->max_data_return);
10075                 END_PROFILE(Trans2_findnotifyfirst);
10076                 break;
10077         }
10078
10079         case TRANSACT2_FINDNOTIFYNEXT:
10080         {
10081                 START_PROFILE(Trans2_findnotifynext);
10082                 call_trans2findnotifynext(conn, req,
10083                                           &state->param, state->total_param,
10084                                           &state->data, state->total_data,
10085                                           state->max_data_return);
10086                 END_PROFILE(Trans2_findnotifynext);
10087                 break;
10088         }
10089
10090         case TRANSACT2_MKDIR:
10091         {
10092                 START_PROFILE(Trans2_mkdir);
10093                 call_trans2mkdir(conn, req,
10094                                  &state->param, state->total_param,
10095                                  &state->data, state->total_data,
10096                                  state->max_data_return);
10097                 END_PROFILE(Trans2_mkdir);
10098                 break;
10099         }
10100
10101         case TRANSACT2_GET_DFS_REFERRAL:
10102         {
10103                 START_PROFILE(Trans2_get_dfs_referral);
10104                 call_trans2getdfsreferral(conn, req,
10105                                           &state->param, state->total_param,
10106                                           &state->data, state->total_data,
10107                                           state->max_data_return);
10108                 END_PROFILE(Trans2_get_dfs_referral);
10109                 break;
10110         }
10111
10112         case TRANSACT2_IOCTL:
10113         {
10114                 START_PROFILE(Trans2_ioctl);
10115                 call_trans2ioctl(conn, req,
10116                                  &state->param, state->total_param,
10117                                  &state->data, state->total_data,
10118                                  state->max_data_return);
10119                 END_PROFILE(Trans2_ioctl);
10120                 break;
10121         }
10122
10123         default:
10124                 /* Error in request */
10125                 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
10126                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
10127         }
10128 }
10129
10130 /****************************************************************************
10131  Reply to a SMBtrans2.
10132  ****************************************************************************/
10133
10134 void reply_trans2(struct smb_request *req)
10135 {
10136         connection_struct *conn = req->conn;
10137         unsigned int dsoff;
10138         unsigned int dscnt;
10139         unsigned int psoff;
10140         unsigned int pscnt;
10141         unsigned int tran_call;
10142         struct trans_state *state;
10143         NTSTATUS result;
10144
10145         START_PROFILE(SMBtrans2);
10146
10147         if (req->wct < 14) {
10148                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10149                 END_PROFILE(SMBtrans2);
10150                 return;
10151         }
10152
10153         dsoff = SVAL(req->vwv+12, 0);
10154         dscnt = SVAL(req->vwv+11, 0);
10155         psoff = SVAL(req->vwv+10, 0);
10156         pscnt = SVAL(req->vwv+9, 0);
10157         tran_call = SVAL(req->vwv+14, 0);
10158
10159         result = allow_new_trans(conn->pending_trans, req->mid);
10160         if (!NT_STATUS_IS_OK(result)) {
10161                 DEBUG(2, ("Got invalid trans2 request: %s\n",
10162                           nt_errstr(result)));
10163                 reply_nterror(req, result);
10164                 END_PROFILE(SMBtrans2);
10165                 return;
10166         }
10167
10168         if (IS_IPC(conn)) {
10169                 switch (tran_call) {
10170                 /* List the allowed trans2 calls on IPC$ */
10171                 case TRANSACT2_OPEN:
10172                 case TRANSACT2_GET_DFS_REFERRAL:
10173                 case TRANSACT2_QFILEINFO:
10174                 case TRANSACT2_QFSINFO:
10175                 case TRANSACT2_SETFSINFO:
10176                         break;
10177                 default:
10178                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
10179                         END_PROFILE(SMBtrans2);
10180                         return;
10181                 }
10182         }
10183
10184         if ((state = talloc(conn, struct trans_state)) == NULL) {
10185                 DEBUG(0, ("talloc failed\n"));
10186                 reply_nterror(req, NT_STATUS_NO_MEMORY);
10187                 END_PROFILE(SMBtrans2);
10188                 return;
10189         }
10190
10191         state->cmd = SMBtrans2;
10192
10193         state->mid = req->mid;
10194         state->vuid = req->vuid;
10195         state->setup_count = SVAL(req->vwv+13, 0);
10196         state->setup = NULL;
10197         state->total_param = SVAL(req->vwv+0, 0);
10198         state->param = NULL;
10199         state->total_data =  SVAL(req->vwv+1, 0);
10200         state->data = NULL;
10201         state->max_param_return = SVAL(req->vwv+2, 0);
10202         state->max_data_return  = SVAL(req->vwv+3, 0);
10203         state->max_setup_return = SVAL(req->vwv+4, 0);
10204         state->close_on_completion = BITSETW(req->vwv+5, 0);
10205         state->one_way = BITSETW(req->vwv+5, 1);
10206
10207         state->call = tran_call;
10208
10209         /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
10210            is so as a sanity check */
10211         if (state->setup_count != 1) {
10212                 /*
10213                  * Need to have rc=0 for ioctl to get job id for OS/2.
10214                  *  Network printing will fail if function is not successful.
10215                  *  Similar function in reply.c will be used if protocol
10216                  *  is LANMAN1.0 instead of LM1.2X002.
10217                  *  Until DosPrintSetJobInfo with PRJINFO3 is supported,
10218                  *  outbuf doesn't have to be set(only job id is used).
10219                  */
10220                 if ( (state->setup_count == 4)
10221                      && (tran_call == TRANSACT2_IOCTL)
10222                      && (SVAL(req->vwv+16, 0) == LMCAT_SPL)
10223                      && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
10224                         DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
10225                 } else {
10226                         DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
10227                         DEBUG(2,("Transaction is %d\n",tran_call));
10228                         TALLOC_FREE(state);
10229                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10230                         END_PROFILE(SMBtrans2);
10231                         return;
10232                 }
10233         }
10234
10235         if ((dscnt > state->total_data) || (pscnt > state->total_param))
10236                 goto bad_param;
10237
10238         if (state->total_data) {
10239
10240                 if (trans_oob(state->total_data, 0, dscnt)
10241                     || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
10242                         goto bad_param;
10243                 }
10244
10245                 /* Can't use talloc here, the core routines do realloc on the
10246                  * params and data. */
10247                 state->data = (char *)SMB_MALLOC(state->total_data);
10248                 if (state->data == NULL) {
10249                         DEBUG(0,("reply_trans2: data malloc fail for %u "
10250                                  "bytes !\n", (unsigned int)state->total_data));
10251                         TALLOC_FREE(state);
10252                         reply_nterror(req, NT_STATUS_NO_MEMORY);
10253                         END_PROFILE(SMBtrans2);
10254                         return;
10255                 }
10256
10257                 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
10258         }
10259
10260         if (state->total_param) {
10261
10262                 if (trans_oob(state->total_param, 0, pscnt)
10263                     || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
10264                         goto bad_param;
10265                 }
10266
10267                 /* Can't use talloc here, the core routines do realloc on the
10268                  * params and data. */
10269                 state->param = (char *)SMB_MALLOC(state->total_param);
10270                 if (state->param == NULL) {
10271                         DEBUG(0,("reply_trans: param malloc fail for %u "
10272                                  "bytes !\n", (unsigned int)state->total_param));
10273                         SAFE_FREE(state->data);
10274                         TALLOC_FREE(state);
10275                         reply_nterror(req, NT_STATUS_NO_MEMORY);
10276                         END_PROFILE(SMBtrans2);
10277                         return;
10278                 } 
10279
10280                 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
10281         }
10282
10283         state->received_data  = dscnt;
10284         state->received_param = pscnt;
10285
10286         if ((state->received_param == state->total_param) &&
10287             (state->received_data == state->total_data)) {
10288
10289                 handle_trans2(conn, req, state);
10290
10291                 SAFE_FREE(state->data);
10292                 SAFE_FREE(state->param);
10293                 TALLOC_FREE(state);
10294                 END_PROFILE(SMBtrans2);
10295                 return;
10296         }
10297
10298         DLIST_ADD(conn->pending_trans, state);
10299
10300         /* We need to send an interim response then receive the rest
10301            of the parameter/data bytes */
10302         reply_outbuf(req, 0, 0);
10303         show_msg((char *)req->outbuf);
10304         END_PROFILE(SMBtrans2);
10305         return;
10306
10307   bad_param:
10308
10309         DEBUG(0,("reply_trans2: invalid trans parameters\n"));
10310         SAFE_FREE(state->data);
10311         SAFE_FREE(state->param);
10312         TALLOC_FREE(state);
10313         END_PROFILE(SMBtrans2);
10314         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10315 }
10316
10317
10318 /****************************************************************************
10319  Reply to a SMBtranss2
10320  ****************************************************************************/
10321
10322 void reply_transs2(struct smb_request *req)
10323 {
10324         connection_struct *conn = req->conn;
10325         unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
10326         struct trans_state *state;
10327
10328         START_PROFILE(SMBtranss2);
10329
10330         show_msg((const char *)req->inbuf);
10331
10332         /* Windows clients expect all replies to
10333            a transact secondary (SMBtranss2 0x33)
10334            to have a command code of transact
10335            (SMBtrans2 0x32). See bug #8989
10336            and also [MS-CIFS] section 2.2.4.47.2
10337            for details.
10338         */
10339         req->cmd = SMBtrans2;
10340
10341         if (req->wct < 8) {
10342                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10343                 END_PROFILE(SMBtranss2);
10344                 return;
10345         }
10346
10347         for (state = conn->pending_trans; state != NULL;
10348              state = state->next) {
10349                 if (state->mid == req->mid) {
10350                         break;
10351                 }
10352         }
10353
10354         if ((state == NULL) || (state->cmd != SMBtrans2)) {
10355                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10356                 END_PROFILE(SMBtranss2);
10357                 return;
10358         }
10359
10360         /* Revise state->total_param and state->total_data in case they have
10361            changed downwards */
10362
10363         if (SVAL(req->vwv+0, 0) < state->total_param)
10364                 state->total_param = SVAL(req->vwv+0, 0);
10365         if (SVAL(req->vwv+1, 0) < state->total_data)
10366                 state->total_data = SVAL(req->vwv+1, 0);
10367
10368         pcnt = SVAL(req->vwv+2, 0);
10369         poff = SVAL(req->vwv+3, 0);
10370         pdisp = SVAL(req->vwv+4, 0);
10371
10372         dcnt = SVAL(req->vwv+5, 0);
10373         doff = SVAL(req->vwv+6, 0);
10374         ddisp = SVAL(req->vwv+7, 0);
10375
10376         state->received_param += pcnt;
10377         state->received_data += dcnt;
10378
10379         if ((state->received_data > state->total_data) ||
10380             (state->received_param > state->total_param))
10381                 goto bad_param;
10382
10383         if (pcnt) {
10384                 if (trans_oob(state->total_param, pdisp, pcnt)
10385                     || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
10386                         goto bad_param;
10387                 }
10388                 memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
10389         }
10390
10391         if (dcnt) {
10392                 if (trans_oob(state->total_data, ddisp, dcnt)
10393                     || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
10394                         goto bad_param;
10395                 }
10396                 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
10397         }
10398
10399         if ((state->received_param < state->total_param) ||
10400             (state->received_data < state->total_data)) {
10401                 END_PROFILE(SMBtranss2);
10402                 return;
10403         }
10404
10405         handle_trans2(conn, req, state);
10406
10407         DLIST_REMOVE(conn->pending_trans, state);
10408         SAFE_FREE(state->data);
10409         SAFE_FREE(state->param);
10410         TALLOC_FREE(state);
10411
10412         END_PROFILE(SMBtranss2);
10413         return;
10414
10415   bad_param:
10416
10417         DEBUG(0,("reply_transs2: invalid trans parameters\n"));
10418         DLIST_REMOVE(conn->pending_trans, state);
10419         SAFE_FREE(state->data);
10420         SAFE_FREE(state->param);
10421         TALLOC_FREE(state);
10422         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10423         END_PROFILE(SMBtranss2);
10424         return;
10425 }