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