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