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