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