s3:smbd: rename get_FileIndex() to get_fs_file_id()
[samba.git] / source3 / smbd / trans2.c
1 /*
2    Unix SMB/CIFS implementation.
3    SMB transaction2 handling
4    Copyright (C) Jeremy Allison                 1994-2007
5    Copyright (C) Stefan (metze) Metzmacher      2003
6    Copyright (C) Volker Lendecke                2005-2007
7    Copyright (C) Steve French                   2005
8    Copyright (C) James Peach                    2006-2007
9
10    Extensively modified by Andrew Tridgell, 1995
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 3 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include "includes.h"
27 #include "ntioctl.h"
28 #include "system/filesys.h"
29 #include "version.h"
30 #include "smbd/smbd.h"
31 #include "smbd/globals.h"
32 #include "../libcli/auth/libcli_auth.h"
33 #include "../librpc/gen_ndr/xattr.h"
34 #include "../librpc/gen_ndr/ndr_security.h"
35 #include "libcli/security/security.h"
36 #include "trans2.h"
37 #include "auth.h"
38 #include "smbprofile.h"
39 #include "rpc_server/srv_pipe_hnd.h"
40 #include "printing.h"
41 #include "lib/util_ea.h"
42 #include "lib/readdir_attr.h"
43 #include "messages.h"
44
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_fs_file_id(connection_struct *conn, const SMB_STRUCT_STAT *psbuf)
223 {
224         uint64_t file_id;
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_id = ((psbuf->st_ex_ino) & UINT32_MAX); /* FileIDLow */
232         file_id |= ((uint64_t)((psbuf->st_ex_dev) & UINT32_MAX)) << 32; /* FileIDHigh */
233         return file_id;
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_id = 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_id = get_fs_file_id(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_id); 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_id); 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         dev_t devno;
4605
4606         DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
4607         DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_ex_mode));
4608
4609         SOFF_T(pdata,0,get_file_size_stat(psbuf));             /* File size 64 Bit */
4610         pdata += 8;
4611
4612         SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
4613         pdata += 8;
4614
4615         put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata, psbuf->st_ex_ctime);       /* Change Time 64 Bit */
4616         put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER ,pdata+8, psbuf->st_ex_atime);     /* Last access time 64 Bit */
4617         put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata+16, psbuf->st_ex_mtime);    /* Last modification time 64 Bit */
4618         pdata += 24;
4619
4620         SIVAL(pdata,0,psbuf->st_ex_uid);               /* user id for the owner */
4621         SIVAL(pdata,4,0);
4622         pdata += 8;
4623
4624         SIVAL(pdata,0,psbuf->st_ex_gid);               /* group id of owner */
4625         SIVAL(pdata,4,0);
4626         pdata += 8;
4627
4628         SIVAL(pdata,0,unix_filetype(psbuf->st_ex_mode));
4629         pdata += 4;
4630
4631         if (S_ISBLK(psbuf->st_ex_mode) || S_ISCHR(psbuf->st_ex_mode)) {
4632                 devno = psbuf->st_ex_rdev;
4633         } else {
4634                 devno = psbuf->st_ex_dev;
4635         }
4636
4637         SIVAL(pdata,0,unix_dev_major(devno));   /* Major device number if type is device */
4638         SIVAL(pdata,4,0);
4639         pdata += 8;
4640
4641         SIVAL(pdata,0,unix_dev_minor(devno));   /* Minor device number if type is device */
4642         SIVAL(pdata,4,0);
4643         pdata += 8;
4644
4645         SINO_T_VAL(pdata, 0, psbuf->st_ex_ino);   /* inode number */
4646         pdata += 8;
4647
4648         SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode));     /* Standard UNIX file permissions */
4649         SIVAL(pdata,4,0);
4650         pdata += 8;
4651
4652         SIVAL(pdata,0,psbuf->st_ex_nlink);             /* number of hard links */
4653         SIVAL(pdata,4,0);
4654         pdata += 8;
4655
4656         return pdata;
4657 }
4658
4659 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
4660  * the chflags(2) (or equivalent) flags.
4661  *
4662  * XXX: this really should be behind the VFS interface. To do this, we would
4663  * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
4664  * Each VFS module could then implement its own mapping as appropriate for the
4665  * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
4666  */
4667 static const struct {unsigned stat_fflag; unsigned smb_fflag;}
4668         info2_flags_map[] =
4669 {
4670 #ifdef UF_NODUMP
4671     { UF_NODUMP, EXT_DO_NOT_BACKUP },
4672 #endif
4673
4674 #ifdef UF_IMMUTABLE
4675     { UF_IMMUTABLE, EXT_IMMUTABLE },
4676 #endif
4677
4678 #ifdef UF_APPEND
4679     { UF_APPEND, EXT_OPEN_APPEND_ONLY },
4680 #endif
4681
4682 #ifdef UF_HIDDEN
4683     { UF_HIDDEN, EXT_HIDDEN },
4684 #endif
4685
4686     /* Do not remove. We need to guarantee that this array has at least one
4687      * entry to build on HP-UX.
4688      */
4689     { 0, 0 }
4690
4691 };
4692
4693 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf,
4694                                 uint32_t *smb_fflags, uint32_t *smb_fmask)
4695 {
4696         int i;
4697
4698         for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
4699             *smb_fmask |= info2_flags_map[i].smb_fflag;
4700             if (psbuf->st_ex_flags & info2_flags_map[i].stat_fflag) {
4701                     *smb_fflags |= info2_flags_map[i].smb_fflag;
4702             }
4703         }
4704 }
4705
4706 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
4707                                 const uint32_t smb_fflags,
4708                                 const uint32_t smb_fmask,
4709                                 int *stat_fflags)
4710 {
4711         uint32_t max_fmask = 0;
4712         int i;
4713
4714         *stat_fflags = psbuf->st_ex_flags;
4715
4716         /* For each flags requested in smb_fmask, check the state of the
4717          * corresponding flag in smb_fflags and set or clear the matching
4718          * stat flag.
4719          */
4720
4721         for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
4722             max_fmask |= info2_flags_map[i].smb_fflag;
4723             if (smb_fmask & info2_flags_map[i].smb_fflag) {
4724                     if (smb_fflags & info2_flags_map[i].smb_fflag) {
4725                             *stat_fflags |= info2_flags_map[i].stat_fflag;
4726                     } else {
4727                             *stat_fflags &= ~info2_flags_map[i].stat_fflag;
4728                     }
4729             }
4730         }
4731
4732         /* If smb_fmask is asking to set any bits that are not supported by
4733          * our flag mappings, we should fail.
4734          */
4735         if ((smb_fmask & max_fmask) != smb_fmask) {
4736                 return False;
4737         }
4738
4739         return True;
4740 }
4741
4742
4743 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
4744  * of file flags and birth (create) time.
4745  */
4746 static char *store_file_unix_basic_info2(connection_struct *conn,
4747                                 char *pdata,
4748                                 files_struct *fsp,
4749                                 const SMB_STRUCT_STAT *psbuf)
4750 {
4751         uint32_t file_flags = 0;
4752         uint32_t flags_mask = 0;
4753
4754         pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
4755
4756         /* Create (birth) time 64 bit */
4757         put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER,pdata, psbuf->st_ex_btime);
4758         pdata += 8;
4759
4760         map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
4761         SIVAL(pdata, 0, file_flags); /* flags */
4762         SIVAL(pdata, 4, flags_mask); /* mask */
4763         pdata += 8;
4764
4765         return pdata;
4766 }
4767
4768 static NTSTATUS marshall_stream_info(unsigned int num_streams,
4769                                      const struct stream_struct *streams,
4770                                      char *data,
4771                                      unsigned int max_data_bytes,
4772                                      unsigned int *data_size)
4773 {
4774         unsigned int i;
4775         unsigned int ofs = 0;
4776
4777         if (max_data_bytes < 32) {
4778                 return NT_STATUS_INFO_LENGTH_MISMATCH;
4779         }
4780
4781         for (i = 0; i < num_streams; i++) {
4782                 unsigned int next_offset;
4783                 size_t namelen;
4784                 smb_ucs2_t *namebuf;
4785
4786                 if (!push_ucs2_talloc(talloc_tos(), &namebuf,
4787                                       streams[i].name, &namelen) ||
4788                     namelen <= 2)
4789                 {
4790                         return NT_STATUS_INVALID_PARAMETER;
4791                 }
4792
4793                 /*
4794                  * name_buf is now null-terminated, we need to marshall as not
4795                  * terminated
4796                  */
4797
4798                 namelen -= 2;
4799
4800                 /*
4801                  * We cannot overflow ...
4802                  */
4803                 if ((ofs + 24 + namelen) > max_data_bytes) {
4804                         DEBUG(10, ("refusing to overflow reply at stream %u\n",
4805                                 i));
4806                         TALLOC_FREE(namebuf);
4807                         return STATUS_BUFFER_OVERFLOW;
4808                 }
4809
4810                 SIVAL(data, ofs+4, namelen);
4811                 SOFF_T(data, ofs+8, streams[i].size);
4812                 SOFF_T(data, ofs+16, streams[i].alloc_size);
4813                 memcpy(data+ofs+24, namebuf, namelen);
4814                 TALLOC_FREE(namebuf);
4815
4816                 next_offset = ofs + 24 + namelen;
4817
4818                 if (i == num_streams-1) {
4819                         SIVAL(data, ofs, 0);
4820                 }
4821                 else {
4822                         unsigned int align = ndr_align_size(next_offset, 8);
4823
4824                         if ((next_offset + align) > max_data_bytes) {
4825                                 DEBUG(10, ("refusing to overflow align "
4826                                         "reply at stream %u\n",
4827                                         i));
4828                                 TALLOC_FREE(namebuf);
4829                                 return STATUS_BUFFER_OVERFLOW;
4830                         }
4831
4832                         memset(data+next_offset, 0, align);
4833                         next_offset += align;
4834
4835                         SIVAL(data, ofs, next_offset - ofs);
4836                         ofs = next_offset;
4837                 }
4838
4839                 ofs = next_offset;
4840         }
4841
4842         DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes, ofs));
4843
4844         *data_size = ofs;
4845
4846         return NT_STATUS_OK;
4847 }
4848
4849 #if defined(HAVE_POSIX_ACLS)
4850 static NTSTATUS smb_query_posix_acl(connection_struct *conn,
4851                                 struct smb_request *req,
4852                                 files_struct *fsp,
4853                                 struct smb_filename *smb_fname,
4854                                 char *pdata,
4855                                 unsigned int data_size_in,
4856                                 unsigned int *pdata_size_out)
4857 {
4858         SMB_ACL_T file_acl = NULL;
4859         SMB_ACL_T def_acl = NULL;
4860         uint16_t num_file_acls = 0;
4861         uint16_t num_def_acls = 0;
4862         unsigned int size_needed = 0;
4863         NTSTATUS status;
4864         bool ok;
4865         bool close_fsp;
4866
4867         /*
4868          * Ensure we always operate on a file descriptor, not just
4869          * the filename.
4870          */
4871         if (fsp == NULL) {
4872                 uint32_t access_mask = SEC_STD_READ_CONTROL|
4873                                         FILE_READ_ATTRIBUTES|
4874                                         FILE_WRITE_ATTRIBUTES;
4875
4876                 status = get_posix_fsp(conn,
4877                                         req,
4878                                         smb_fname,
4879                                         access_mask,
4880                                         &fsp);
4881
4882                 if (!NT_STATUS_IS_OK(status)) {
4883                         goto out;
4884                 }
4885                 close_fsp = true;
4886         }
4887
4888         SMB_ASSERT(fsp != NULL);
4889
4890         status = refuse_symlink(conn,
4891                                 fsp,
4892                                 fsp->fsp_name);
4893         if (!NT_STATUS_IS_OK(status)) {
4894                 goto out;
4895         }
4896
4897         file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp,
4898                                         talloc_tos());
4899
4900         if (file_acl == NULL && no_acl_syscall_error(errno)) {
4901                 DBG_INFO("ACLs not implemented on "
4902                         "filesystem containing %s\n",
4903                         fsp_str_dbg(fsp));
4904                 status = NT_STATUS_NOT_IMPLEMENTED;
4905                 goto out;
4906         }
4907
4908         if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4909                 /*
4910                  * We can only have default POSIX ACLs on
4911                  * directories.
4912                  */
4913                 if (!fsp->is_directory) {
4914                         DBG_INFO("Non-directory open %s\n",
4915                                 fsp_str_dbg(fsp));
4916                         status = NT_STATUS_INVALID_HANDLE;
4917                         goto out;
4918                 }
4919                 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn,
4920                                         fsp->fsp_name,
4921                                         SMB_ACL_TYPE_DEFAULT,
4922                                         talloc_tos());
4923                 def_acl = free_empty_sys_acl(conn, def_acl);
4924         }
4925
4926         num_file_acls = count_acl_entries(conn, file_acl);
4927         num_def_acls = count_acl_entries(conn, def_acl);
4928
4929         /* Wrap checks. */
4930         if (num_file_acls + num_def_acls < num_file_acls) {
4931                 status = NT_STATUS_INVALID_PARAMETER;
4932                 goto out;
4933         }
4934
4935         size_needed = num_file_acls + num_def_acls;
4936
4937         /*
4938          * (size_needed * SMB_POSIX_ACL_ENTRY_SIZE) must be less
4939          * than UINT_MAX, so check by division.
4940          */
4941         if (size_needed > (UINT_MAX/SMB_POSIX_ACL_ENTRY_SIZE)) {
4942                 status = NT_STATUS_INVALID_PARAMETER;
4943                 goto out;
4944         }
4945
4946         size_needed = size_needed*SMB_POSIX_ACL_ENTRY_SIZE;
4947         if (size_needed + SMB_POSIX_ACL_HEADER_SIZE < size_needed) {
4948                 status = NT_STATUS_INVALID_PARAMETER;
4949                 goto out;
4950         }
4951         size_needed += SMB_POSIX_ACL_HEADER_SIZE;
4952
4953         if ( data_size_in < size_needed) {
4954                 DBG_INFO("data_size too small (%u) need %u\n",
4955                         data_size_in,
4956                         size_needed);
4957                 status = NT_STATUS_BUFFER_TOO_SMALL;
4958                 goto out;
4959         }
4960
4961         SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
4962         SSVAL(pdata,2,num_file_acls);
4963         SSVAL(pdata,4,num_def_acls);
4964         pdata += SMB_POSIX_ACL_HEADER_SIZE;
4965
4966         ok = marshall_posix_acl(conn,
4967                         pdata,
4968                         &fsp->fsp_name->st,
4969                         file_acl);
4970         if (!ok) {
4971                 status = NT_STATUS_INTERNAL_ERROR;
4972                 goto out;
4973         }
4974         pdata += (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE);
4975
4976         ok = marshall_posix_acl(conn,
4977                         pdata,
4978                         &fsp->fsp_name->st,
4979                         def_acl);
4980         if (!ok) {
4981                 status = NT_STATUS_INTERNAL_ERROR;
4982                 goto out;
4983         }
4984
4985         *pdata_size_out = size_needed;
4986         status = NT_STATUS_OK;
4987
4988   out:
4989
4990         if (close_fsp) {
4991                 /*
4992                  * Ensure the stat struct in smb_fname is up to
4993                  * date. Structure copy.
4994                  */
4995                 smb_fname->st = fsp->fsp_name->st;
4996                 (void)close_file(req, fsp, NORMAL_CLOSE);
4997                 fsp = NULL;
4998         }
4999
5000         TALLOC_FREE(file_acl);
5001         TALLOC_FREE(def_acl);
5002         return status;
5003 }
5004 #endif
5005
5006 /****************************************************************************
5007  Reply to a TRANSACT2_QFILEINFO on a PIPE !
5008 ****************************************************************************/
5009
5010 static void call_trans2qpipeinfo(connection_struct *conn,
5011                                  struct smb_request *req,
5012                                  unsigned int tran_call,
5013                                  char **pparams, int total_params,
5014                                  char **ppdata, int total_data,
5015                                  unsigned int max_data_bytes)
5016 {
5017         char *params = *pparams;
5018         char *pdata = *ppdata;
5019         unsigned int data_size = 0;
5020         unsigned int param_size = 2;
5021         uint16_t info_level;
5022         files_struct *fsp;
5023
5024         if (!params) {
5025                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5026                 return;
5027         }
5028
5029         if (total_params < 4) {
5030                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5031                 return;
5032         }
5033
5034         fsp = file_fsp(req, SVAL(params,0));
5035         if (!fsp_is_np(fsp)) {
5036                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
5037                 return;
5038         }
5039
5040         info_level = SVAL(params,2);
5041
5042         *pparams = (char *)SMB_REALLOC(*pparams,2);
5043         if (*pparams == NULL) {
5044                 reply_nterror(req, NT_STATUS_NO_MEMORY);
5045                 return;
5046         }
5047         params = *pparams;
5048         SSVAL(params,0,0);
5049         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
5050                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5051                 return;
5052         }
5053         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
5054         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 
5055         if (*ppdata == NULL ) {
5056                 reply_nterror(req, NT_STATUS_NO_MEMORY);
5057                 return;
5058         }
5059         pdata = *ppdata;
5060
5061         switch (info_level) {
5062                 case SMB_FILE_STANDARD_INFORMATION:
5063                         memset(pdata,0,24);
5064                         SOFF_T(pdata,0,4096LL);
5065                         SIVAL(pdata,16,1);
5066                         SIVAL(pdata,20,1);
5067                         data_size = 24;
5068                         break;
5069
5070                 default:
5071                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5072                         return;
5073         }
5074
5075         send_trans2_replies(conn, req, NT_STATUS_OK, params, param_size, *ppdata, data_size,
5076                             max_data_bytes);
5077
5078         return;
5079 }
5080
5081 NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
5082                                TALLOC_CTX *mem_ctx,
5083                                struct smb_request *req,
5084                                uint16_t info_level,
5085                                files_struct *fsp,
5086                                struct smb_filename *smb_fname,
5087                                bool delete_pending,
5088                                struct timespec write_time_ts,
5089                                struct ea_list *ea_list,
5090                                int lock_data_count,
5091                                char *lock_data,
5092                                uint16_t flags2,
5093                                unsigned int max_data_bytes,
5094                                size_t *fixed_portion,
5095                                char **ppdata,
5096                                unsigned int *pdata_size)
5097 {
5098         char *pdata = *ppdata;
5099         char *dstart, *dend;
5100         unsigned int data_size;
5101         struct timespec create_time_ts, mtime_ts, atime_ts, ctime_ts;
5102         time_t create_time, mtime, atime, c_time;
5103         SMB_STRUCT_STAT *psbuf = &smb_fname->st;
5104         char *p;
5105         char *base_name;
5106         char *dos_fname;
5107         int mode;
5108         int nlink;
5109         NTSTATUS status;
5110         uint64_t file_size = 0;
5111         uint64_t pos = 0;
5112         uint64_t allocation_size = 0;
5113         uint64_t file_id = 0;
5114         uint32_t access_mask = 0;
5115         size_t len = 0;
5116
5117         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
5118                 return NT_STATUS_INVALID_LEVEL;
5119         }
5120
5121         DEBUG(5,("smbd_do_qfilepathinfo: %s (%s) level=%d max_data=%u\n",
5122                  smb_fname_str_dbg(smb_fname),
5123                  fsp_fnum_dbg(fsp),
5124                  info_level, max_data_bytes));
5125
5126         mode = dos_mode(conn, smb_fname);
5127         nlink = psbuf->st_ex_nlink;
5128
5129         if (nlink && (mode&FILE_ATTRIBUTE_DIRECTORY)) {
5130                 nlink = 1;
5131         }
5132
5133         if ((nlink > 0) && delete_pending) {
5134                 nlink -= 1;
5135         }
5136
5137         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
5138                 return NT_STATUS_INVALID_PARAMETER;
5139         }
5140
5141         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
5142         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 
5143         if (*ppdata == NULL) {
5144                 return NT_STATUS_NO_MEMORY;
5145         }
5146         pdata = *ppdata;
5147         dstart = pdata;
5148         dend = dstart + data_size - 1;
5149
5150         if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
5151                 update_stat_ex_mtime(psbuf, write_time_ts);
5152         }
5153
5154         create_time_ts = get_create_timespec(conn, fsp, smb_fname);
5155         mtime_ts = psbuf->st_ex_mtime;
5156         atime_ts = psbuf->st_ex_atime;
5157         ctime_ts = get_change_timespec(conn, fsp, smb_fname);
5158
5159         if (lp_dos_filetime_resolution(SNUM(conn))) {
5160                 dos_filetime_timespec(&create_time_ts);
5161                 dos_filetime_timespec(&mtime_ts);
5162                 dos_filetime_timespec(&atime_ts);
5163                 dos_filetime_timespec(&ctime_ts);
5164         }
5165
5166         create_time = convert_timespec_to_time_t(create_time_ts);
5167         mtime = convert_timespec_to_time_t(mtime_ts);
5168         atime = convert_timespec_to_time_t(atime_ts);
5169         c_time = convert_timespec_to_time_t(ctime_ts);
5170
5171         p = strrchr_m(smb_fname->base_name,'/');
5172         if (!p)
5173                 base_name = smb_fname->base_name;
5174         else
5175                 base_name = p+1;
5176
5177         /* NT expects the name to be in an exact form of the *full*
5178            filename. See the trans2 torture test */
5179         if (ISDOT(base_name)) {
5180                 dos_fname = talloc_strdup(mem_ctx, "\\");
5181                 if (!dos_fname) {
5182                         return NT_STATUS_NO_MEMORY;
5183                 }
5184         } else {
5185                 dos_fname = talloc_asprintf(mem_ctx,
5186                                 "\\%s",
5187                                 smb_fname->base_name);
5188                 if (!dos_fname) {
5189                         return NT_STATUS_NO_MEMORY;
5190                 }
5191                 if (is_ntfs_stream_smb_fname(smb_fname)) {
5192                         dos_fname = talloc_asprintf(dos_fname, "%s",
5193                                                     smb_fname->stream_name);
5194                         if (!dos_fname) {
5195                                 return NT_STATUS_NO_MEMORY;
5196                         }
5197                 }
5198
5199                 string_replace(dos_fname, '/', '\\');
5200         }
5201
5202         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, psbuf);
5203
5204         if (!fsp) {
5205                 /* Do we have this path open ? */
5206                 files_struct *fsp1;
5207                 struct file_id fileid = vfs_file_id_from_sbuf(conn, psbuf);
5208                 fsp1 = file_find_di_first(conn->sconn, fileid);
5209                 if (fsp1 && fsp1->initial_allocation_size) {
5210                         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, psbuf);
5211                 }
5212         }
5213
5214         if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
5215                 file_size = get_file_size_stat(psbuf);
5216         }
5217
5218         if (fsp) {
5219                 pos = fsp->fh->position_information;
5220         }
5221
5222         if (fsp) {
5223                 access_mask = fsp->access_mask;
5224         } else {
5225                 /* GENERIC_EXECUTE mapping from Windows */
5226                 access_mask = 0x12019F;
5227         }
5228
5229         /* This should be an index number - looks like
5230            dev/ino to me :-)
5231
5232            I think this causes us to fail the IFSKIT
5233            BasicFileInformationTest. -tpot */
5234         file_id = get_fs_file_id(conn, psbuf);
5235
5236         *fixed_portion = 0;
5237
5238         switch (info_level) {
5239                 case SMB_INFO_STANDARD:
5240                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
5241                         data_size = 22;
5242                         srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
5243                         srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
5244                         srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
5245                         SIVAL(pdata,l1_cbFile,(uint32_t)file_size);
5246                         SIVAL(pdata,l1_cbFileAlloc,(uint32_t)allocation_size);
5247                         SSVAL(pdata,l1_attrFile,mode);
5248                         break;
5249
5250                 case SMB_INFO_QUERY_EA_SIZE:
5251                 {
5252                         unsigned int ea_size =
5253                             estimate_ea_size(conn, fsp,
5254                                              smb_fname);
5255                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
5256                         data_size = 26;
5257                         srv_put_dos_date2(pdata,0,create_time);
5258                         srv_put_dos_date2(pdata,4,atime);
5259                         srv_put_dos_date2(pdata,8,mtime); /* write time */
5260                         SIVAL(pdata,12,(uint32_t)file_size);
5261                         SIVAL(pdata,16,(uint32_t)allocation_size);
5262                         SSVAL(pdata,20,mode);
5263                         SIVAL(pdata,22,ea_size);
5264                         break;
5265                 }
5266
5267                 case SMB_INFO_IS_NAME_VALID:
5268                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
5269                         if (fsp) {
5270                                 /* os/2 needs this ? really ?*/
5271                                 return NT_STATUS_DOS(ERRDOS, ERRbadfunc);
5272                         }
5273                         /* This is only reached for qpathinfo */
5274                         data_size = 0;
5275                         break;
5276
5277                 case SMB_INFO_QUERY_EAS_FROM_LIST:
5278                 {
5279                         size_t total_ea_len = 0;
5280                         struct ea_list *ea_file_list = NULL;
5281                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
5282
5283                         status =
5284                             get_ea_list_from_file(mem_ctx, conn, fsp,
5285                                                   smb_fname,
5286                                                   &total_ea_len, &ea_file_list);
5287                         if (!NT_STATUS_IS_OK(status)) {
5288                                 return status;
5289                         }
5290
5291                         ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
5292
5293                         if (!ea_list || (total_ea_len > data_size)) {
5294                                 data_size = 4;
5295                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
5296                                 break;
5297                         }
5298
5299                         data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
5300                         break;
5301                 }
5302
5303                 case SMB_INFO_QUERY_ALL_EAS:
5304                 {
5305                         /* We have data_size bytes to put EA's into. */
5306                         size_t total_ea_len = 0;
5307                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
5308
5309                         status = get_ea_list_from_file(mem_ctx, conn, fsp,
5310                                                         smb_fname,
5311                                                         &total_ea_len, &ea_list);
5312                         if (!NT_STATUS_IS_OK(status)) {
5313                                 return status;
5314                         }
5315
5316                         if (!ea_list || (total_ea_len > data_size)) {
5317                                 data_size = 4;
5318                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
5319                                 break;
5320                         }
5321
5322                         data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
5323                         break;
5324                 }
5325
5326                 case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
5327                 {
5328                         /* This is FileFullEaInformation - 0xF which maps to
5329                          * 1015 (decimal) in smbd_do_setfilepathinfo. */
5330
5331                         /* We have data_size bytes to put EA's into. */
5332                         size_t total_ea_len = 0;
5333                         struct ea_list *ea_file_list = NULL;
5334
5335                         DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
5336
5337                         /*TODO: add filtering and index handling */
5338
5339                         status  =
5340                                 get_ea_list_from_file(mem_ctx, conn, fsp,
5341                                                   smb_fname,
5342                                                   &total_ea_len, &ea_file_list);
5343                         if (!NT_STATUS_IS_OK(status)) {
5344                                 return status;
5345                         }
5346                         if (!ea_file_list) {
5347                                 return NT_STATUS_NO_EAS_ON_FILE;
5348                         }
5349
5350                         status = fill_ea_chained_buffer(mem_ctx,
5351                                                         pdata,
5352                                                         data_size,
5353                                                         &data_size,
5354                                                         conn, ea_file_list);
5355                         if (!NT_STATUS_IS_OK(status)) {
5356                                 return status;
5357                         }
5358                         break;
5359                 }
5360
5361                 case SMB_FILE_BASIC_INFORMATION:
5362                 case SMB_QUERY_FILE_BASIC_INFO:
5363
5364                         if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
5365                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
5366                                 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
5367                         } else {
5368                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
5369                                 data_size = 40;
5370                                 SIVAL(pdata,36,0);
5371                         }
5372                         put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
5373                         put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
5374                         put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
5375                         put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
5376                         SIVAL(pdata,32,mode);
5377
5378                         DEBUG(5,("SMB_QFBI - "));
5379                         DEBUG(5,("create: %s ", ctime(&create_time)));
5380                         DEBUG(5,("access: %s ", ctime(&atime)));
5381                         DEBUG(5,("write: %s ", ctime(&mtime)));
5382                         DEBUG(5,("change: %s ", ctime(&c_time)));
5383                         DEBUG(5,("mode: %x\n", mode));
5384                         *fixed_portion = data_size;
5385                         break;
5386
5387                 case SMB_FILE_STANDARD_INFORMATION:
5388                 case SMB_QUERY_FILE_STANDARD_INFO:
5389
5390                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
5391                         data_size = 24;
5392                         SOFF_T(pdata,0,allocation_size);
5393                         SOFF_T(pdata,8,file_size);
5394                         SIVAL(pdata,16,nlink);
5395                         SCVAL(pdata,20,delete_pending?1:0);
5396                         SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
5397                         SSVAL(pdata,22,0); /* Padding. */
5398                         *fixed_portion = 24;
5399                         break;
5400
5401                 case SMB_FILE_EA_INFORMATION:
5402                 case SMB_QUERY_FILE_EA_INFO:
5403                 {
5404                         unsigned int ea_size =
5405                             estimate_ea_size(conn, fsp, smb_fname);
5406                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
5407                         data_size = 4;
5408                         *fixed_portion = 4;
5409                         SIVAL(pdata,0,ea_size);
5410                         break;
5411                 }
5412
5413                 /* Get the 8.3 name - used if NT SMB was negotiated. */
5414                 case SMB_QUERY_FILE_ALT_NAME_INFO:
5415                 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
5416                 {
5417                         char mangled_name[13];
5418                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
5419                         if (!name_to_8_3(base_name,mangled_name,
5420                                                 True,conn->params)) {
5421                                 return NT_STATUS_NO_MEMORY;
5422                         }
5423                         status = srvstr_push(dstart, flags2,
5424                                           pdata+4, mangled_name,
5425                                           PTR_DIFF(dend, pdata+4),
5426                                           STR_UNICODE, &len);
5427                         if (!NT_STATUS_IS_OK(status)) {
5428                                 return status;
5429                         }
5430                         data_size = 4 + len;
5431                         SIVAL(pdata,0,len);
5432                         *fixed_portion = 8;
5433                         break;
5434                 }
5435
5436                 case SMB_QUERY_FILE_NAME_INFO:
5437                 {
5438                         /*
5439                           this must be *exactly* right for ACLs on mapped drives to work
5440                          */
5441                         status = srvstr_push(dstart, flags2,
5442                                           pdata+4, dos_fname,
5443                                           PTR_DIFF(dend, pdata+4),
5444                                           STR_UNICODE, &len);
5445                         if (!NT_STATUS_IS_OK(status)) {
5446                                 return status;
5447                         }
5448                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
5449                         data_size = 4 + len;
5450                         SIVAL(pdata,0,len);
5451                         break;
5452                 }
5453
5454                 case SMB_FILE_NORMALIZED_NAME_INFORMATION:
5455                 {
5456                         char *nfname = NULL;
5457
5458                         if (!fsp->conn->sconn->using_smb2) {
5459                                 return NT_STATUS_INVALID_LEVEL;
5460                         }
5461
5462                         nfname = talloc_strdup(mem_ctx, smb_fname->base_name);
5463                         if (nfname == NULL) {
5464                                 return NT_STATUS_NO_MEMORY;
5465                         }
5466
5467                         if (ISDOT(nfname)) {
5468                                 nfname[0] = '\0';
5469                         }
5470                         string_replace(nfname, '/', '\\');
5471
5472                         if (smb_fname->stream_name != NULL) {
5473                                 const char *s = smb_fname->stream_name;
5474                                 const char *e = NULL;
5475                                 size_t n;
5476
5477                                 SMB_ASSERT(s[0] != '\0');
5478
5479                                 /*
5480                                  * smb_fname->stream_name is in form
5481                                  * of ':StrEam:$DATA', but we should only
5482                                  * append ':StrEam' here.
5483                                  */
5484
5485                                 e = strchr(&s[1], ':');
5486                                 if (e == NULL) {
5487                                         n = strlen(s);
5488                                 } else {
5489                                         n = PTR_DIFF(e, s);
5490                                 }
5491                                 nfname = talloc_strndup_append(nfname, s, n);
5492                                 if (nfname == NULL) {
5493                                         return NT_STATUS_NO_MEMORY;
5494                                 }
5495                         }
5496
5497                         status = srvstr_push(dstart, flags2,
5498                                           pdata+4, nfname,
5499                                           PTR_DIFF(dend, pdata+4),
5500                                           STR_UNICODE, &len);
5501                         if (!NT_STATUS_IS_OK(status)) {
5502                                 return status;
5503                         }
5504                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NORMALIZED_NAME_INFORMATION\n"));
5505                         data_size = 4 + len;
5506                         SIVAL(pdata,0,len);
5507                         *fixed_portion = 8;
5508                         break;
5509                 }
5510
5511                 case SMB_FILE_ALLOCATION_INFORMATION:
5512                 case SMB_QUERY_FILE_ALLOCATION_INFO:
5513                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
5514                         data_size = 8;
5515                         SOFF_T(pdata,0,allocation_size);
5516                         break;
5517
5518                 case SMB_FILE_END_OF_FILE_INFORMATION:
5519                 case SMB_QUERY_FILE_END_OF_FILEINFO:
5520                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
5521                         data_size = 8;
5522                         SOFF_T(pdata,0,file_size);
5523                         break;
5524
5525                 case SMB_QUERY_FILE_ALL_INFO:
5526                 case SMB_FILE_ALL_INFORMATION:
5527                 {
5528                         unsigned int ea_size =
5529                             estimate_ea_size(conn, fsp, smb_fname);
5530                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
5531                         put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
5532                         put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
5533                         put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
5534                         put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
5535                         SIVAL(pdata,32,mode);
5536                         SIVAL(pdata,36,0); /* padding. */
5537                         pdata += 40;
5538                         SOFF_T(pdata,0,allocation_size);
5539                         SOFF_T(pdata,8,file_size);
5540                         SIVAL(pdata,16,nlink);
5541                         SCVAL(pdata,20,delete_pending);
5542                         SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
5543                         SSVAL(pdata,22,0);
5544                         pdata += 24;
5545                         SIVAL(pdata,0,ea_size);
5546                         pdata += 4; /* EA info */
5547                         status = srvstr_push(dstart, flags2,
5548                                           pdata+4, dos_fname,
5549                                           PTR_DIFF(dend, pdata+4),
5550                                           STR_UNICODE, &len);
5551                         if (!NT_STATUS_IS_OK(status)) {
5552                                 return status;
5553                         }
5554                         SIVAL(pdata,0,len);
5555                         pdata += 4 + len;
5556                         data_size = PTR_DIFF(pdata,(*ppdata));
5557                         *fixed_portion = 10;
5558                         break;
5559                 }
5560
5561                 case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
5562                 {
5563                         unsigned int ea_size =
5564                             estimate_ea_size(conn, fsp, smb_fname);
5565                         DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
5566                         put_long_date_timespec(conn->ts_res,pdata+0x00,create_time_ts);
5567                         put_long_date_timespec(conn->ts_res,pdata+0x08,atime_ts);
5568                         put_long_date_timespec(conn->ts_res,pdata+0x10,mtime_ts); /* write time */
5569                         put_long_date_timespec(conn->ts_res,pdata+0x18,ctime_ts); /* change time */
5570                         SIVAL(pdata,    0x20, mode);
5571                         SIVAL(pdata,    0x24, 0); /* padding. */
5572                         SBVAL(pdata,    0x28, allocation_size);
5573                         SBVAL(pdata,    0x30, file_size);
5574                         SIVAL(pdata,    0x38, nlink);
5575                         SCVAL(pdata,    0x3C, delete_pending);
5576                         SCVAL(pdata,    0x3D, (mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
5577                         SSVAL(pdata,    0x3E, 0); /* padding */
5578                         SBVAL(pdata,    0x40, file_id);
5579                         SIVAL(pdata,    0x48, ea_size);
5580                         SIVAL(pdata,    0x4C, access_mask);
5581                         SBVAL(pdata,    0x50, pos);
5582                         SIVAL(pdata,    0x58, mode); /*TODO: mode != mode fix this!!! */
5583                         SIVAL(pdata,    0x5C, 0); /* No alignment needed. */
5584
5585                         pdata += 0x60;
5586
5587                         status = srvstr_push(dstart, flags2,
5588                                           pdata+4, dos_fname,
5589                                           PTR_DIFF(dend, pdata+4),
5590                                           STR_UNICODE, &len);
5591                         if (!NT_STATUS_IS_OK(status)) {
5592                                 return status;
5593                         }
5594                         SIVAL(pdata,0,len);
5595                         pdata += 4 + len;
5596                         data_size = PTR_DIFF(pdata,(*ppdata));
5597                         *fixed_portion = 104;
5598                         break;
5599                 }
5600                 case SMB_FILE_INTERNAL_INFORMATION:
5601
5602                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
5603                         SBVAL(pdata, 0, file_id);
5604                         data_size = 8;
5605                         *fixed_portion = 8;
5606                         break;
5607
5608                 case SMB_FILE_ACCESS_INFORMATION:
5609                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
5610                         SIVAL(pdata, 0, access_mask);
5611                         data_size = 4;
5612                         *fixed_portion = 4;
5613                         break;
5614
5615                 case SMB_FILE_NAME_INFORMATION:
5616                         /* Pathname with leading '\'. */
5617                         {
5618                                 size_t byte_len;
5619                                 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
5620                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
5621                                 SIVAL(pdata,0,byte_len);
5622                                 data_size = 4 + byte_len;
5623                                 break;
5624                         }
5625
5626                 case SMB_FILE_DISPOSITION_INFORMATION:
5627                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
5628                         data_size = 1;
5629                         SCVAL(pdata,0,delete_pending);
5630                         *fixed_portion = 1;
5631                         break;
5632
5633                 case SMB_FILE_POSITION_INFORMATION:
5634                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
5635                         data_size = 8;
5636                         SOFF_T(pdata,0,pos);
5637                         *fixed_portion = 8;
5638                         break;
5639
5640                 case SMB_FILE_MODE_INFORMATION:
5641                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
5642                         SIVAL(pdata,0,mode);
5643                         data_size = 4;
5644                         *fixed_portion = 4;
5645                         break;
5646
5647                 case SMB_FILE_ALIGNMENT_INFORMATION:
5648                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
5649                         SIVAL(pdata,0,0); /* No alignment needed. */
5650                         data_size = 4;
5651                         *fixed_portion = 4;
5652                         break;
5653
5654                 /*
5655                  * NT4 server just returns "invalid query" to this - if we try
5656                  * to answer it then NTws gets a BSOD! (tridge).  W2K seems to
5657                  * want this. JRA.
5658                  */
5659                 /* The first statement above is false - verified using Thursby
5660                  * client against NT4 -- gcolley.
5661                  */
5662                 case SMB_QUERY_FILE_STREAM_INFO:
5663                 case SMB_FILE_STREAM_INFORMATION: {
5664                         unsigned int num_streams = 0;
5665                         struct stream_struct *streams = NULL;
5666
5667                         DEBUG(10,("smbd_do_qfilepathinfo: "
5668                                   "SMB_FILE_STREAM_INFORMATION\n"));
5669
5670                         if (is_ntfs_stream_smb_fname(smb_fname)) {
5671                                 return NT_STATUS_INVALID_PARAMETER;
5672                         }
5673
5674                         status = vfs_streaminfo(conn,
5675                                                 fsp,
5676                                                 smb_fname,
5677                                                 talloc_tos(),
5678                                                 &num_streams,
5679                                                 &streams);
5680
5681                         if (!NT_STATUS_IS_OK(status)) {
5682                                 DEBUG(10, ("could not get stream info: %s\n",
5683                                            nt_errstr(status)));
5684                                 return status;
5685                         }
5686
5687                         status = marshall_stream_info(num_streams, streams,
5688                                                       pdata, max_data_bytes,
5689                                                       &data_size);
5690
5691                         if (!NT_STATUS_IS_OK(status)) {
5692                                 DEBUG(10, ("marshall_stream_info failed: %s\n",
5693                                            nt_errstr(status)));
5694                                 TALLOC_FREE(streams);
5695                                 return status;
5696                         }
5697
5698                         TALLOC_FREE(streams);
5699
5700                         *fixed_portion = 32;
5701
5702                         break;
5703                 }
5704                 case SMB_QUERY_COMPRESSION_INFO:
5705                 case SMB_FILE_COMPRESSION_INFORMATION:
5706                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
5707                         SOFF_T(pdata,0,file_size);
5708                         SIVAL(pdata,8,0); /* ??? */
5709                         SIVAL(pdata,12,0); /* ??? */
5710                         data_size = 16;
5711                         *fixed_portion = 16;
5712                         break;
5713
5714                 case SMB_FILE_NETWORK_OPEN_INFORMATION:
5715                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
5716                         put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
5717                         put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
5718                         put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
5719                         put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
5720                         SOFF_T(pdata,32,allocation_size);
5721                         SOFF_T(pdata,40,file_size);
5722                         SIVAL(pdata,48,mode);
5723                         SIVAL(pdata,52,0); /* ??? */
5724                         data_size = 56;
5725                         *fixed_portion = 56;
5726                         break;
5727
5728                 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
5729                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
5730                         SIVAL(pdata,0,mode);
5731                         SIVAL(pdata,4,0);
5732                         data_size = 8;
5733                         *fixed_portion = 8;
5734                         break;
5735
5736                 /*
5737                  * CIFS UNIX Extensions.
5738                  */
5739
5740                 case SMB_QUERY_FILE_UNIX_BASIC:
5741
5742                         pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
5743                         data_size = PTR_DIFF(pdata,(*ppdata));
5744
5745                         DEBUG(4,("smbd_do_qfilepathinfo: "
5746                                  "SMB_QUERY_FILE_UNIX_BASIC\n"));
5747                         dump_data(4, (uint8_t *)(*ppdata), data_size);
5748
5749                         break;
5750
5751                 case SMB_QUERY_FILE_UNIX_INFO2:
5752
5753                         pdata = store_file_unix_basic_info2(conn, pdata, fsp, psbuf);
5754                         data_size = PTR_DIFF(pdata,(*ppdata));
5755
5756                         {
5757                                 int i;
5758                                 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
5759
5760                                 for (i=0; i<100; i++)
5761                                         DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
5762                                 DEBUG(4,("\n"));
5763                         }
5764
5765                         break;
5766
5767                 case SMB_QUERY_FILE_UNIX_LINK:
5768                         {
5769                                 int link_len = 0;
5770                                 char *buffer = talloc_array(mem_ctx, char, PATH_MAX+1);
5771
5772                                 if (!buffer) {
5773                                         return NT_STATUS_NO_MEMORY;
5774                                 }
5775
5776                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
5777 #ifdef S_ISLNK
5778                                 if(!S_ISLNK(psbuf->st_ex_mode)) {
5779                                         return NT_STATUS_DOS(ERRSRV, ERRbadlink);
5780                                 }
5781 #else
5782                                 return NT_STATUS_DOS(ERRDOS, ERRbadlink);
5783 #endif
5784                                 link_len = SMB_VFS_READLINK(conn,
5785                                                        smb_fname,
5786                                                        buffer, PATH_MAX);
5787                                 if (link_len == -1) {
5788                                         return map_nt_error_from_unix(errno);
5789                                 }
5790                                 buffer[link_len] = 0;
5791                                 status = srvstr_push(dstart, flags2,
5792                                                   pdata, buffer,
5793                                                   PTR_DIFF(dend, pdata),
5794                                                   STR_TERMINATE, &len);
5795                                 if (!NT_STATUS_IS_OK(status)) {
5796                                         return status;
5797                                 }
5798                                 pdata += len;
5799                                 data_size = PTR_DIFF(pdata,(*ppdata));
5800
5801                                 break;
5802                         }
5803
5804 #if defined(HAVE_POSIX_ACLS)
5805                 case SMB_QUERY_POSIX_ACL:
5806                         {
5807                                 status = smb_query_posix_acl(conn,
5808                                                         req,
5809                                                         fsp,
5810                                                         smb_fname,
5811                                                         pdata,
5812                                                         data_size,
5813                                                         &data_size);
5814                                 if (!NT_STATUS_IS_OK(status)) {
5815                                         return status;
5816                                 }
5817                                 break;
5818                         }
5819 #endif
5820
5821
5822                 case SMB_QUERY_POSIX_LOCK:
5823                 {
5824                         uint64_t count;
5825                         uint64_t offset;
5826                         uint64_t smblctx;
5827                         enum brl_type lock_type;
5828
5829                         /* We need an open file with a real fd for this. */
5830                         if (!fsp || fsp->fh->fd == -1) {
5831                                 return NT_STATUS_INVALID_LEVEL;
5832                         }
5833
5834                         if (lock_data_count != POSIX_LOCK_DATA_SIZE) {
5835                                 return NT_STATUS_INVALID_PARAMETER;
5836                         }
5837
5838                         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
5839                                 case POSIX_LOCK_TYPE_READ:
5840                                         lock_type = READ_LOCK;
5841                                         break;
5842                                 case POSIX_LOCK_TYPE_WRITE:
5843                                         lock_type = WRITE_LOCK;
5844                                         break;
5845                                 case POSIX_LOCK_TYPE_UNLOCK:
5846                                 default:
5847                                         /* There's no point in asking for an unlock... */
5848                                         return NT_STATUS_INVALID_PARAMETER;
5849                         }
5850
5851                         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
5852                         offset = BVAL(pdata,POSIX_LOCK_START_OFFSET);
5853                         count = BVAL(pdata,POSIX_LOCK_LEN_OFFSET);
5854
5855                         status = query_lock(fsp,
5856                                         &smblctx,
5857                                         &count,
5858                                         &offset,
5859                                         &lock_type,
5860                                         POSIX_LOCK);
5861
5862                         if (ERROR_WAS_LOCK_DENIED(status)) {
5863                                 /* Here we need to report who has it locked... */
5864                                 data_size = POSIX_LOCK_DATA_SIZE;
5865
5866                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
5867                                 SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
5868                                 SIVAL(pdata, POSIX_LOCK_PID_OFFSET, (uint32_t)smblctx);
5869                                 SBVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
5870                                 SBVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
5871
5872                         } else if (NT_STATUS_IS_OK(status)) {
5873                                 /* For success we just return a copy of what we sent
5874                                    with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
5875                                 data_size = POSIX_LOCK_DATA_SIZE;
5876                                 memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
5877                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
5878                         } else {
5879                                 return status;
5880                         }
5881                         break;
5882                 }
5883
5884                 default:
5885                         return NT_STATUS_INVALID_LEVEL;
5886         }
5887
5888         *pdata_size = data_size;
5889         return NT_STATUS_OK;
5890 }
5891
5892 /****************************************************************************
5893  Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
5894  file name or file id).
5895 ****************************************************************************/
5896
5897 static void call_trans2qfilepathinfo(connection_struct *conn,
5898                                      struct smb_request *req,
5899                                      unsigned int tran_call,
5900                                      char **pparams, int total_params,
5901                                      char **ppdata, int total_data,
5902                                      unsigned int max_data_bytes)
5903 {
5904         char *params = *pparams;
5905         char *pdata = *ppdata;
5906         uint16_t info_level;
5907         unsigned int data_size = 0;
5908         unsigned int param_size = 2;
5909         struct smb_filename *smb_fname = NULL;
5910         bool delete_pending = False;
5911         struct timespec write_time_ts;
5912         files_struct *fsp = NULL;
5913         struct file_id fileid;
5914         struct ea_list *ea_list = NULL;
5915         int lock_data_count = 0;
5916         char *lock_data = NULL;
5917         size_t fixed_portion;
5918         NTSTATUS status = NT_STATUS_OK;
5919
5920         if (!params) {
5921                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5922                 return;
5923         }
5924
5925         ZERO_STRUCT(write_time_ts);
5926
5927         if (tran_call == TRANSACT2_QFILEINFO) {
5928                 if (total_params < 4) {
5929                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5930                         return;
5931                 }
5932
5933                 if (IS_IPC(conn)) {
5934                         call_trans2qpipeinfo(conn, req, tran_call,
5935                                              pparams, total_params,
5936                                              ppdata, total_data,
5937                                              max_data_bytes);
5938                         return;
5939                 }
5940
5941                 fsp = file_fsp(req, SVAL(params,0));
5942                 info_level = SVAL(params,2);
5943
5944                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
5945
5946                 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
5947                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5948                         return;
5949                 }
5950
5951                 /* Initial check for valid fsp ptr. */
5952                 if (!check_fsp_open(conn, req, fsp)) {
5953                         return;
5954                 }
5955
5956                 smb_fname = cp_smb_filename(talloc_tos(), fsp->fsp_name);
5957                 if (smb_fname == NULL) {
5958                         reply_nterror(req, NT_STATUS_NO_MEMORY);
5959                         return;
5960                 }
5961
5962                 if(fsp->fake_file_handle) {
5963                         /*
5964                          * This is actually for the QUOTA_FAKE_FILE --metze
5965                          */
5966
5967                         /* We know this name is ok, it's already passed the checks. */
5968
5969                 } else if(fsp->fh->fd == -1) {
5970                         /*
5971                          * This is actually a QFILEINFO on a directory
5972                          * handle (returned from an NT SMB). NT5.0 seems
5973                          * to do this call. JRA.
5974                          */
5975
5976                         if (INFO_LEVEL_IS_UNIX(info_level)) {
5977                                 /* Always do lstat for UNIX calls. */
5978                                 if (SMB_VFS_LSTAT(conn, smb_fname)) {
5979                                         DEBUG(3,("call_trans2qfilepathinfo: "
5980                                                  "SMB_VFS_LSTAT of %s failed "
5981                                                  "(%s)\n",
5982                                                  smb_fname_str_dbg(smb_fname),
5983                                                  strerror(errno)));
5984                                         reply_nterror(req,
5985                                                 map_nt_error_from_unix(errno));
5986                                         return;
5987                                 }
5988                         } else if (SMB_VFS_STAT(conn, smb_fname)) {
5989                                 DEBUG(3,("call_trans2qfilepathinfo: "
5990                                          "SMB_VFS_STAT of %s failed (%s)\n",
5991                                          smb_fname_str_dbg(smb_fname),
5992                                          strerror(errno)));
5993                                 reply_nterror(req,
5994                                         map_nt_error_from_unix(errno));
5995                                 return;
5996                         }
5997
5998                         if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
5999                                 fileid = vfs_file_id_from_sbuf(
6000                                         conn, &smb_fname->st);
6001                                 get_file_infos(fileid, fsp->name_hash,
6002                                                &delete_pending,
6003                                                &write_time_ts);
6004                         }
6005                 } else {
6006                         /*
6007                          * Original code - this is an open file.
6008                          */
6009                         if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
6010                                 DEBUG(3, ("fstat of %s failed (%s)\n",
6011                                           fsp_fnum_dbg(fsp), strerror(errno)));
6012                                 reply_nterror(req,
6013                                         map_nt_error_from_unix(errno));
6014                                 return;
6015                         }
6016                         if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
6017                                 fileid = vfs_file_id_from_sbuf(
6018                                         conn, &smb_fname->st);
6019                                 get_file_infos(fileid, fsp->name_hash,
6020                                                &delete_pending,
6021                                                &write_time_ts);
6022                         }
6023                 }
6024
6025         } else {
6026                 uint32_t name_hash;
6027                 char *fname = NULL;
6028                 uint32_t ucf_flags = ucf_flags_from_smb_request(req);
6029
6030                 /* qpathinfo */
6031                 if (total_params < 7) {
6032                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6033                         return;
6034                 }
6035
6036                 info_level = SVAL(params,0);
6037
6038                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
6039
6040                 if (INFO_LEVEL_IS_UNIX(info_level)) {
6041                         if (!lp_unix_extensions()) {
6042                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
6043                                 return;
6044                         }
6045                         if (info_level == SMB_QUERY_FILE_UNIX_BASIC ||
6046                                         info_level == SMB_QUERY_FILE_UNIX_INFO2 ||
6047                                         info_level == SMB_QUERY_FILE_UNIX_LINK ||
6048                                         req->posix_pathnames) {
6049                                 ucf_flags |= UCF_UNIX_NAME_LOOKUP;
6050                         }
6051                 }
6052
6053                 if (req->posix_pathnames) {
6054                         srvstr_get_path_posix(req,
6055                                 params,
6056                                 req->flags2,
6057                                 &fname,
6058                                 &params[6],
6059                                 total_params - 6,
6060                                 STR_TERMINATE,
6061                                 &status);
6062                 } else {
6063                         srvstr_get_path(req,
6064                                 params,
6065                                 req->flags2,
6066                                 &fname,
6067                                 &params[6],
6068                                 total_params - 6,
6069                                 STR_TERMINATE,
6070                                 &status);
6071                 }
6072                 if (!NT_STATUS_IS_OK(status)) {
6073                         reply_nterror(req, status);
6074                         return;
6075                 }
6076
6077                 status = filename_convert(req,
6078                                         conn,
6079                                         fname,
6080                                         ucf_flags,
6081                                         NULL,
6082                                         NULL,
6083                                         &smb_fname);
6084                 if (!NT_STATUS_IS_OK(status)) {
6085                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6086                                 reply_botherror(req,
6087                                                 NT_STATUS_PATH_NOT_COVERED,
6088                                                 ERRSRV, ERRbadpath);
6089                                 return;
6090                         }
6091                         reply_nterror(req, status);
6092                         return;
6093                 }
6094
6095                 /* If this is a stream, check if there is a delete_pending. */
6096                 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6097                     && is_ntfs_stream_smb_fname(smb_fname)) {
6098                         struct smb_filename *smb_fname_base;
6099
6100                         /* Create an smb_filename with stream_name == NULL. */
6101                         smb_fname_base = synthetic_smb_fname(
6102                                                 talloc_tos(),
6103                                                 smb_fname->base_name,
6104                                                 NULL,
6105                                                 NULL,
6106                                                 smb_fname->flags);
6107                         if (smb_fname_base == NULL) {
6108                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
6109                                 return;
6110                         }
6111
6112                         if (INFO_LEVEL_IS_UNIX(info_level) || req->posix_pathnames) {
6113                                 /* Always do lstat for UNIX calls. */
6114                                 if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
6115                                         DEBUG(3,("call_trans2qfilepathinfo: "
6116                                                  "SMB_VFS_LSTAT of %s failed "
6117                                                  "(%s)\n",
6118                                                  smb_fname_str_dbg(smb_fname_base),
6119                                                  strerror(errno)));
6120                                         TALLOC_FREE(smb_fname_base);
6121                                         reply_nterror(req,
6122                                                 map_nt_error_from_unix(errno));
6123                                         return;
6124                                 }
6125                         } else {
6126                                 if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
6127                                         DEBUG(3,("call_trans2qfilepathinfo: "
6128                                                  "fileinfo of %s failed "
6129                                                  "(%s)\n",
6130                                                  smb_fname_str_dbg(smb_fname_base),
6131                                                  strerror(errno)));
6132                                         TALLOC_FREE(smb_fname_base);
6133                                         reply_nterror(req,
6134                                                 map_nt_error_from_unix(errno));
6135                                         return;
6136                                 }
6137                         }
6138
6139                         status = file_name_hash(conn,
6140                                         smb_fname_str_dbg(smb_fname_base),
6141                                         &name_hash);
6142                         if (!NT_STATUS_IS_OK(status)) {
6143                                 TALLOC_FREE(smb_fname_base);
6144                                 reply_nterror(req, status);
6145                                 return;
6146                         }
6147
6148                         fileid = vfs_file_id_from_sbuf(conn,
6149                                                        &smb_fname_base->st);
6150                         TALLOC_FREE(smb_fname_base);
6151                         get_file_infos(fileid, name_hash, &delete_pending, NULL);
6152                         if (delete_pending) {
6153                                 reply_nterror(req, NT_STATUS_DELETE_PENDING);
6154                                 return;
6155                         }
6156                 }
6157
6158                 if (INFO_LEVEL_IS_UNIX(info_level) || req->posix_pathnames) {
6159                         /* Always do lstat for UNIX calls. */
6160                         if (SMB_VFS_LSTAT(conn, smb_fname)) {
6161                                 DEBUG(3,("call_trans2qfilepathinfo: "
6162                                          "SMB_VFS_LSTAT of %s failed (%s)\n",
6163                                          smb_fname_str_dbg(smb_fname),
6164                                          strerror(errno)));
6165                                 reply_nterror(req,
6166                                         map_nt_error_from_unix(errno));
6167                                 return;
6168                         }
6169
6170                 } else {
6171                         if (SMB_VFS_STAT(conn, smb_fname) != 0) {
6172                                 DEBUG(3,("call_trans2qfilepathinfo: "
6173                                          "SMB_VFS_STAT of %s failed (%s)\n",
6174                                          smb_fname_str_dbg(smb_fname),
6175                                          strerror(errno)));
6176                                 reply_nterror(req,
6177                                         map_nt_error_from_unix(errno));
6178                                 return;
6179                         }
6180                 }
6181
6182                 status = file_name_hash(conn,
6183                                 smb_fname_str_dbg(smb_fname),
6184                                 &name_hash);
6185                 if (!NT_STATUS_IS_OK(status)) {
6186                         reply_nterror(req, status);
6187                         return;
6188                 }
6189
6190                 if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
6191                         fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
6192                         get_file_infos(fileid, name_hash, &delete_pending,
6193                                        &write_time_ts);
6194                 }
6195
6196                 if (delete_pending) {
6197                         reply_nterror(req, NT_STATUS_DELETE_PENDING);
6198                         return;
6199                 }
6200         }
6201
6202         DEBUG(3,("call_trans2qfilepathinfo %s (%s) level=%d call=%d "
6203                  "total_data=%d\n", smb_fname_str_dbg(smb_fname),
6204                  fsp_fnum_dbg(fsp),
6205                  info_level,tran_call,total_data));
6206
6207         /* Pull out any data sent here before we realloc. */
6208         switch (info_level) {
6209                 case SMB_INFO_QUERY_EAS_FROM_LIST:
6210                 {
6211                         /* Pull any EA list from the data portion. */
6212                         uint32_t ea_size;
6213
6214                         if (total_data < 4) {
6215                                 reply_nterror(
6216                                         req, NT_STATUS_INVALID_PARAMETER);
6217                                 return;
6218                         }
6219                         ea_size = IVAL(pdata,0);
6220
6221                         if (total_data > 0 && ea_size != total_data) {
6222                                 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
6223 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
6224                                 reply_nterror(
6225                                         req, NT_STATUS_INVALID_PARAMETER);
6226                                 return;
6227                         }
6228
6229                         if (!lp_ea_support(SNUM(conn))) {
6230                                 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
6231                                 return;
6232                         }
6233
6234                         /* Pull out the list of names. */
6235                         ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4);
6236                         if (!ea_list) {
6237                                 reply_nterror(
6238                                         req, NT_STATUS_INVALID_PARAMETER);
6239                                 return;
6240                         }
6241                         break;
6242                 }
6243
6244                 case SMB_QUERY_POSIX_LOCK:
6245                 {
6246                         if (fsp == NULL || fsp->fh->fd == -1) {
6247                                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
6248                                 return;
6249                         }
6250
6251                         if (total_data != POSIX_LOCK_DATA_SIZE) {
6252                                 reply_nterror(
6253                                         req, NT_STATUS_INVALID_PARAMETER);
6254                                 return;
6255                         }
6256
6257                         /* Copy the lock range data. */
6258                         lock_data = (char *)talloc_memdup(
6259                                 req, pdata, total_data);
6260                         if (!lock_data) {
6261                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
6262                                 return;
6263                         }
6264                         lock_data_count = total_data;
6265                 }
6266                 default:
6267                         break;
6268         }
6269
6270         *pparams = (char *)SMB_REALLOC(*pparams,2);
6271         if (*pparams == NULL) {
6272                 reply_nterror(req, NT_STATUS_NO_MEMORY);
6273                 return;
6274         }
6275         params = *pparams;
6276         SSVAL(params,0,0);
6277
6278         /*
6279          * draft-leach-cifs-v1-spec-02.txt
6280          * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
6281          * says:
6282          *
6283          *  The requested information is placed in the Data portion of the
6284          *  transaction response. For the information levels greater than 0x100,
6285          *  the transaction response has 1 parameter word which should be
6286          *  ignored by the client.
6287          *
6288          * However Windows only follows this rule for the IS_NAME_VALID call.
6289          */
6290         switch (info_level) {
6291         case SMB_INFO_IS_NAME_VALID:
6292                 param_size = 0;
6293                 break;
6294         }
6295
6296         if ((info_level & 0xFF00) == 0xFF00) {
6297                 /*
6298                  * We use levels that start with 0xFF00
6299                  * internally to represent SMB2 specific levels
6300                  */
6301                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
6302                 return;
6303         }
6304
6305         status = smbd_do_qfilepathinfo(conn, req, req, info_level,
6306                                        fsp, smb_fname,
6307                                        delete_pending, write_time_ts,
6308                                        ea_list,
6309                                        lock_data_count, lock_data,
6310                                        req->flags2, max_data_bytes,
6311                                        &fixed_portion,
6312                                        ppdata, &data_size);
6313         if (!NT_STATUS_IS_OK(status)) {
6314                 if (open_was_deferred(req->xconn, req->mid)) {
6315                         /* We have re-scheduled this call. */
6316                         return;
6317                 }
6318                 reply_nterror(req, status);
6319                 return;
6320         }
6321         if (fixed_portion > max_data_bytes) {
6322                 reply_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH);
6323                 return;
6324         }
6325
6326         send_trans2_replies(conn, req, NT_STATUS_OK, params, param_size, *ppdata, data_size,
6327                             max_data_bytes);
6328
6329         return;
6330 }
6331
6332 /****************************************************************************
6333  Set a hard link (called by UNIX extensions and by NT rename with HARD link
6334  code.
6335 ****************************************************************************/
6336
6337 NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
6338                 connection_struct *conn,
6339                 struct smb_request *req,
6340                 bool overwrite_if_exists,
6341                 const struct smb_filename *smb_fname_old,
6342                 struct smb_filename *smb_fname_new)
6343 {
6344         NTSTATUS status = NT_STATUS_OK;
6345         bool ok;
6346
6347         /* source must already exist. */
6348         if (!VALID_STAT(smb_fname_old->st)) {
6349                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6350         }
6351
6352         if (VALID_STAT(smb_fname_new->st)) {
6353                 if (overwrite_if_exists) {
6354                         if (S_ISDIR(smb_fname_new->st.st_ex_mode)) {
6355                                 return NT_STATUS_FILE_IS_A_DIRECTORY;
6356                         }
6357                         status = unlink_internals(conn,
6358                                                 req,
6359                                                 FILE_ATTRIBUTE_NORMAL,
6360                                                 smb_fname_new,
6361                                                 false);
6362                         if (!NT_STATUS_IS_OK(status)) {
6363                                 return status;
6364                         }
6365                 } else {
6366                         /* Disallow if newname already exists. */
6367                         return NT_STATUS_OBJECT_NAME_COLLISION;
6368                 }
6369         }
6370
6371         /* No links from a directory. */
6372         if (S_ISDIR(smb_fname_old->st.st_ex_mode)) {
6373                 return NT_STATUS_FILE_IS_A_DIRECTORY;
6374         }
6375
6376         /* Setting a hardlink to/from a stream isn't currently supported. */
6377         ok = is_ntfs_stream_smb_fname(smb_fname_old);
6378         if (ok) {
6379                 DBG_DEBUG("Old name has streams\n");
6380                 return NT_STATUS_INVALID_PARAMETER;
6381         }
6382         ok = is_ntfs_stream_smb_fname(smb_fname_new);
6383         if (ok) {
6384                 DBG_DEBUG("New name has streams\n");
6385                 return NT_STATUS_INVALID_PARAMETER;
6386         }
6387
6388         DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
6389                   smb_fname_old->base_name, smb_fname_new->base_name));
6390
6391         if (SMB_VFS_LINK(conn, smb_fname_old, smb_fname_new) != 0) {
6392                 status = map_nt_error_from_unix(errno);
6393                 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
6394                          nt_errstr(status), smb_fname_old->base_name,
6395                          smb_fname_new->base_name));
6396         }
6397         return status;
6398 }
6399
6400 /****************************************************************************
6401  Deal with setting the time from any of the setfilepathinfo functions.
6402  NOTE !!!! The check for FILE_WRITE_ATTRIBUTES access must be done *before*
6403  calling this function.
6404 ****************************************************************************/
6405
6406 NTSTATUS smb_set_file_time(connection_struct *conn,
6407                            files_struct *fsp,
6408                            const struct smb_filename *smb_fname,
6409                            struct smb_file_time *ft,
6410                            bool setting_write_time)
6411 {
6412         struct smb_filename smb_fname_base;
6413         uint32_t action =
6414                 FILE_NOTIFY_CHANGE_LAST_ACCESS
6415                 |FILE_NOTIFY_CHANGE_LAST_WRITE
6416                 |FILE_NOTIFY_CHANGE_CREATION;
6417
6418         if (!VALID_STAT(smb_fname->st)) {
6419                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6420         }
6421
6422         /* get some defaults (no modifications) if any info is zero or -1. */
6423         if (null_timespec(ft->create_time)) {
6424                 action &= ~FILE_NOTIFY_CHANGE_CREATION;
6425         }
6426
6427         if (null_timespec(ft->atime)) {
6428                 action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
6429         }
6430
6431         if (null_timespec(ft->mtime)) {
6432                 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
6433         }
6434
6435         if (!setting_write_time) {
6436                 /* ft->mtime comes from change time, not write time. */
6437                 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
6438         }
6439
6440         /* Ensure the resolution is the correct for
6441          * what we can store on this filesystem. */
6442
6443         round_timespec(conn->ts_res, &ft->create_time);
6444         round_timespec(conn->ts_res, &ft->ctime);
6445         round_timespec(conn->ts_res, &ft->atime);
6446         round_timespec(conn->ts_res, &ft->mtime);
6447
6448         DEBUG(5,("smb_set_filetime: actime: %s\n ",
6449                 time_to_asc(convert_timespec_to_time_t(ft->atime))));
6450         DEBUG(5,("smb_set_filetime: modtime: %s\n ",
6451                 time_to_asc(convert_timespec_to_time_t(ft->mtime))));
6452         DEBUG(5,("smb_set_filetime: ctime: %s\n ",
6453                 time_to_asc(convert_timespec_to_time_t(ft->ctime))));
6454         DEBUG(5,("smb_set_file_time: createtime: %s\n ",
6455                 time_to_asc(convert_timespec_to_time_t(ft->create_time))));
6456
6457         if (setting_write_time) {
6458                 /*
6459                  * This was a Windows setfileinfo on an open file.
6460                  * NT does this a lot. We also need to 
6461                  * set the time here, as it can be read by 
6462                  * FindFirst/FindNext and with the patch for bug #2045
6463                  * in smbd/fileio.c it ensures that this timestamp is
6464                  * kept sticky even after a write. We save the request
6465                  * away and will set it on file close and after a write. JRA.
6466                  */
6467
6468                 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
6469                           time_to_asc(convert_timespec_to_time_t(ft->mtime))));
6470
6471                 if (fsp != NULL) {
6472                         if (fsp->base_fsp) {
6473                                 set_sticky_write_time_fsp(fsp->base_fsp,
6474                                                           ft->mtime);
6475                         } else {
6476                                 set_sticky_write_time_fsp(fsp, ft->mtime);
6477                         }
6478                 } else {
6479                         set_sticky_write_time_path(
6480                                 vfs_file_id_from_sbuf(conn, &smb_fname->st),
6481                                 ft->mtime);
6482                 }
6483         }
6484
6485         DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
6486
6487         /* Always call ntimes on the base, even if a stream was passed in. */
6488         smb_fname_base = *smb_fname;
6489         smb_fname_base.stream_name = NULL;
6490
6491         if(file_ntimes(conn, &smb_fname_base, ft)!=0) {
6492                 return map_nt_error_from_unix(errno);
6493         }
6494
6495         notify_fname(conn, NOTIFY_ACTION_MODIFIED, action,
6496                      smb_fname->base_name);
6497         return NT_STATUS_OK;
6498 }
6499
6500 /****************************************************************************
6501  Deal with setting the dosmode from any of the setfilepathinfo functions.
6502  NB. The check for FILE_WRITE_ATTRIBUTES access on this path must have been
6503  done before calling this function.
6504 ****************************************************************************/
6505
6506 static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
6507                                      const struct smb_filename *smb_fname,
6508                                      uint32_t dosmode)
6509 {
6510         struct smb_filename *smb_fname_base;
6511         NTSTATUS status;
6512
6513         if (!VALID_STAT(smb_fname->st)) {
6514                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6515         }
6516
6517         /* Always operate on the base_name, even if a stream was passed in. */
6518         smb_fname_base = synthetic_smb_fname(talloc_tos(),
6519                                         smb_fname->base_name,
6520                                         NULL,
6521                                         &smb_fname->st,
6522                                         smb_fname->flags);
6523         if (smb_fname_base == NULL) {
6524                 return NT_STATUS_NO_MEMORY;
6525         }
6526
6527         if (dosmode) {
6528                 if (S_ISDIR(smb_fname_base->st.st_ex_mode)) {
6529                         dosmode |= FILE_ATTRIBUTE_DIRECTORY;
6530                 } else {
6531                         dosmode &= ~FILE_ATTRIBUTE_DIRECTORY;
6532                 }
6533         }
6534
6535         DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode));
6536
6537         /* check the mode isn't different, before changing it */
6538         if ((dosmode != 0) && (dosmode != dos_mode(conn, smb_fname_base))) {
6539                 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
6540                           "0x%x\n", smb_fname_str_dbg(smb_fname_base),
6541                           (unsigned int)dosmode));
6542
6543                 if(file_set_dosmode(conn, smb_fname_base, dosmode, NULL,
6544                                     false)) {
6545                         DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
6546                                  "%s failed (%s)\n",
6547                                  smb_fname_str_dbg(smb_fname_base),
6548                                  strerror(errno)));
6549                         status = map_nt_error_from_unix(errno);
6550                         goto out;
6551                 }
6552         }
6553         status = NT_STATUS_OK;
6554  out:
6555         TALLOC_FREE(smb_fname_base);
6556         return status;
6557 }
6558
6559 /****************************************************************************
6560  Deal with setting the size from any of the setfilepathinfo functions.
6561 ****************************************************************************/
6562
6563 static NTSTATUS smb_set_file_size(connection_struct *conn,
6564                                   struct smb_request *req,
6565                                   files_struct *fsp,
6566                                   const struct smb_filename *smb_fname,
6567                                   const SMB_STRUCT_STAT *psbuf,
6568                                   off_t size,
6569                                   bool fail_after_createfile)
6570 {
6571         NTSTATUS status = NT_STATUS_OK;
6572         struct smb_filename *smb_fname_tmp = NULL;
6573         files_struct *new_fsp = NULL;
6574
6575         if (!VALID_STAT(*psbuf)) {
6576                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6577         }
6578
6579         DBG_INFO("size: %"PRIu64", file_size_stat=%"PRIu64"\n",
6580                  (uint64_t)size,
6581                  get_file_size_stat(psbuf));
6582
6583         if (size == get_file_size_stat(psbuf)) {
6584                 return NT_STATUS_OK;
6585         }
6586
6587         DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
6588                   smb_fname_str_dbg(smb_fname), (double)size));
6589
6590         if (fsp && fsp->fh->fd != -1) {
6591                 /* Handle based call. */
6592                 if (!(fsp->access_mask & FILE_WRITE_DATA)) {
6593                         return NT_STATUS_ACCESS_DENIED;
6594                 }
6595
6596                 if (vfs_set_filelen(fsp, size) == -1) {
6597                         return map_nt_error_from_unix(errno);
6598                 }
6599                 trigger_write_time_update_immediate(fsp);
6600                 return NT_STATUS_OK;
6601         }
6602
6603         smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
6604         if (smb_fname_tmp == NULL) {
6605                 return NT_STATUS_NO_MEMORY;
6606         }
6607
6608         smb_fname_tmp->st = *psbuf;
6609
6610         status = SMB_VFS_CREATE_FILE(
6611                 conn,                                   /* conn */
6612                 req,                                    /* req */
6613                 0,                                      /* root_dir_fid */
6614                 smb_fname_tmp,                          /* fname */
6615                 FILE_WRITE_DATA,                        /* access_mask */
6616                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
6617                     FILE_SHARE_DELETE),
6618                 FILE_OPEN,                              /* create_disposition*/
6619                 0,                                      /* create_options */
6620                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
6621                 0,                                      /* oplock_request */
6622                 NULL,                                   /* lease */
6623                 0,                                      /* allocation_size */
6624                 0,                                      /* private_flags */
6625                 NULL,                                   /* sd */
6626                 NULL,                                   /* ea_list */
6627                 &new_fsp,                               /* result */
6628                 NULL,                                   /* pinfo */
6629                 NULL, NULL);                            /* create context */
6630
6631         TALLOC_FREE(smb_fname_tmp);
6632
6633         if (!NT_STATUS_IS_OK(status)) {
6634                 /* NB. We check for open_was_deferred in the caller. */
6635                 return status;
6636         }
6637
6638         /* See RAW-SFILEINFO-END-OF-FILE */
6639         if (fail_after_createfile) {
6640                 close_file(req, new_fsp,NORMAL_CLOSE);
6641                 return NT_STATUS_INVALID_LEVEL;
6642         }
6643
6644         if (vfs_set_filelen(new_fsp, size) == -1) {
6645                 status = map_nt_error_from_unix(errno);
6646                 close_file(req, new_fsp,NORMAL_CLOSE);
6647                 return status;
6648         }
6649
6650         trigger_write_time_update_immediate(new_fsp);
6651         close_file(req, new_fsp,NORMAL_CLOSE);
6652         return NT_STATUS_OK;
6653 }
6654
6655 /****************************************************************************
6656  Deal with SMB_INFO_SET_EA.
6657 ****************************************************************************/
6658
6659 static NTSTATUS smb_info_set_ea(connection_struct *conn,
6660                                 const char *pdata,
6661                                 int total_data,
6662                                 files_struct *fsp,
6663                                 const struct smb_filename *smb_fname)
6664 {
6665         struct ea_list *ea_list = NULL;
6666         TALLOC_CTX *ctx = NULL;
6667         NTSTATUS status = NT_STATUS_OK;
6668
6669         if (total_data < 10) {
6670
6671                 /* OS/2 workplace shell seems to send SET_EA requests of "null"
6672                    length. They seem to have no effect. Bug #3212. JRA */
6673
6674                 if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
6675                         /* We're done. We only get EA info in this call. */
6676                         return NT_STATUS_OK;
6677                 }
6678
6679                 return NT_STATUS_INVALID_PARAMETER;
6680         }
6681
6682         if (IVAL(pdata,0) > total_data) {
6683                 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
6684                         IVAL(pdata,0), (unsigned int)total_data));
6685                 return NT_STATUS_INVALID_PARAMETER;
6686         }
6687
6688         ctx = talloc_tos();
6689         ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
6690         if (!ea_list) {
6691                 return NT_STATUS_INVALID_PARAMETER;
6692         }
6693
6694         status = set_ea(conn, fsp, smb_fname, ea_list);
6695
6696         return status;
6697 }
6698
6699 /****************************************************************************
6700  Deal with SMB_FILE_FULL_EA_INFORMATION set.
6701 ****************************************************************************/
6702
6703 static NTSTATUS smb_set_file_full_ea_info(connection_struct *conn,
6704                                 const char *pdata,
6705                                 int total_data,
6706                                 files_struct *fsp)
6707 {
6708         struct ea_list *ea_list = NULL;
6709         NTSTATUS status;
6710
6711         if (!fsp) {
6712                 return NT_STATUS_INVALID_HANDLE;
6713         }
6714
6715         if (!lp_ea_support(SNUM(conn))) {
6716                 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
6717                         "EA's not supported.\n",
6718                         (unsigned int)total_data));
6719                 return NT_STATUS_EAS_NOT_SUPPORTED;
6720         }
6721
6722         if (total_data < 10) {
6723                 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
6724                         "too small.\n",
6725                         (unsigned int)total_data));
6726                 return NT_STATUS_INVALID_PARAMETER;
6727         }
6728
6729         ea_list = read_nttrans_ea_list(talloc_tos(),
6730                                 pdata,
6731                                 total_data);
6732
6733         if (!ea_list) {
6734                 return NT_STATUS_INVALID_PARAMETER;
6735         }
6736
6737         status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
6738
6739         DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
6740                 smb_fname_str_dbg(fsp->fsp_name),
6741                 nt_errstr(status) ));
6742
6743         return status;
6744 }
6745
6746
6747 /****************************************************************************
6748  Deal with SMB_SET_FILE_DISPOSITION_INFO.
6749 ****************************************************************************/
6750
6751 static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
6752                                 const char *pdata,
6753                                 int total_data,
6754                                 files_struct *fsp,
6755                                 struct smb_filename *smb_fname)
6756 {
6757         NTSTATUS status = NT_STATUS_OK;
6758         bool delete_on_close;
6759         uint32_t dosmode = 0;
6760
6761         if (total_data < 1) {
6762                 return NT_STATUS_INVALID_PARAMETER;
6763         }
6764
6765         if (fsp == NULL) {
6766                 return NT_STATUS_INVALID_HANDLE;
6767         }
6768
6769         delete_on_close = (CVAL(pdata,0) ? True : False);
6770         dosmode = dos_mode(conn, smb_fname);
6771
6772         DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
6773                 "delete_on_close = %u\n",
6774                 smb_fname_str_dbg(smb_fname),
6775                 (unsigned int)dosmode,
6776                 (unsigned int)delete_on_close ));
6777
6778         if (delete_on_close) {
6779                 status = can_set_delete_on_close(fsp, dosmode);
6780                 if (!NT_STATUS_IS_OK(status)) {
6781                         return status;
6782                 }
6783         }
6784
6785         /* The set is across all open files on this dev/inode pair. */
6786         if (!set_delete_on_close(fsp, delete_on_close,
6787                                  conn->session_info->security_token,
6788                                  conn->session_info->unix_token)) {
6789                 return NT_STATUS_ACCESS_DENIED;
6790         }
6791         return NT_STATUS_OK;
6792 }
6793
6794 /****************************************************************************
6795  Deal with SMB_FILE_POSITION_INFORMATION.
6796 ****************************************************************************/
6797
6798 static NTSTATUS smb_file_position_information(connection_struct *conn,
6799                                 const char *pdata,
6800                                 int total_data,
6801                                 files_struct *fsp)
6802 {
6803         uint64_t position_information;
6804
6805         if (total_data < 8) {
6806                 return NT_STATUS_INVALID_PARAMETER;
6807         }
6808
6809         if (fsp == NULL) {
6810                 /* Ignore on pathname based set. */
6811                 return NT_STATUS_OK;
6812         }
6813
6814         position_information = (uint64_t)IVAL(pdata,0);
6815         position_information |= (((uint64_t)IVAL(pdata,4)) << 32);
6816
6817         DEBUG(10,("smb_file_position_information: Set file position "
6818                   "information for file %s to %.0f\n", fsp_str_dbg(fsp),
6819                   (double)position_information));
6820         fsp->fh->position_information = position_information;
6821         return NT_STATUS_OK;
6822 }
6823
6824 /****************************************************************************
6825  Deal with SMB_FILE_MODE_INFORMATION.
6826 ****************************************************************************/
6827
6828 static NTSTATUS smb_file_mode_information(connection_struct *conn,
6829                                 const char *pdata,
6830                                 int total_data)
6831 {
6832         uint32_t mode;
6833
6834         if (total_data < 4) {
6835                 return NT_STATUS_INVALID_PARAMETER;
6836         }
6837         mode = IVAL(pdata,0);
6838         if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
6839                 return NT_STATUS_INVALID_PARAMETER;
6840         }
6841         return NT_STATUS_OK;
6842 }
6843
6844 /****************************************************************************
6845  Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
6846 ****************************************************************************/
6847
6848 static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
6849                                        struct smb_request *req,
6850                                        const char *pdata,
6851                                        int total_data,
6852                                        const struct smb_filename *new_smb_fname)
6853 {
6854         char *link_target = NULL;
6855         TALLOC_CTX *ctx = talloc_tos();
6856
6857         /* Set a symbolic link. */
6858         /* Don't allow this if follow links is false. */
6859
6860         if (total_data == 0) {
6861                 return NT_STATUS_INVALID_PARAMETER;
6862         }
6863
6864         if (!lp_follow_symlinks(SNUM(conn))) {
6865                 return NT_STATUS_ACCESS_DENIED;
6866         }
6867
6868         srvstr_pull_talloc(ctx, pdata, req->flags2, &link_target, pdata,
6869                     total_data, STR_TERMINATE);
6870
6871         if (!link_target) {
6872                 return NT_STATUS_INVALID_PARAMETER;
6873         }
6874
6875         DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
6876                         new_smb_fname->base_name, link_target ));
6877
6878         if (SMB_VFS_SYMLINK(conn,link_target,new_smb_fname) != 0) {
6879                 return map_nt_error_from_unix(errno);
6880         }
6881
6882         return NT_STATUS_OK;
6883 }
6884
6885 /****************************************************************************
6886  Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
6887 ****************************************************************************/
6888
6889 static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
6890                                         struct smb_request *req,
6891                                         const char *pdata, int total_data,
6892                                         struct smb_filename *smb_fname_new)
6893 {
6894         char *oldname = NULL;
6895         struct smb_filename *smb_fname_old = NULL;
6896         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
6897         TALLOC_CTX *ctx = talloc_tos();
6898         NTSTATUS status = NT_STATUS_OK;
6899
6900         /* Set a hard link. */
6901         if (total_data == 0) {
6902                 return NT_STATUS_INVALID_PARAMETER;
6903         }
6904
6905         if (req->posix_pathnames) {
6906                 srvstr_get_path_posix(ctx,
6907                         pdata,
6908                         req->flags2,
6909                         &oldname,
6910                         pdata,
6911                         total_data,
6912                         STR_TERMINATE,
6913                         &status);
6914         } else {
6915                 srvstr_get_path(ctx,
6916                         pdata,
6917                         req->flags2,
6918                         &oldname,
6919                         pdata,
6920                         total_data,
6921                         STR_TERMINATE,
6922                         &status);
6923         }
6924         if (!NT_STATUS_IS_OK(status)) {
6925                 return status;
6926         }
6927
6928         DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
6929                 smb_fname_str_dbg(smb_fname_new), oldname));
6930
6931         status = filename_convert(ctx,
6932                                 conn,
6933                                 oldname,
6934                                 ucf_flags,
6935                                 NULL,
6936                                 NULL,
6937                                 &smb_fname_old);
6938         if (!NT_STATUS_IS_OK(status)) {
6939                 return status;
6940         }
6941
6942         return hardlink_internals(ctx, conn, req, false,
6943                         smb_fname_old, smb_fname_new);
6944 }
6945
6946 /****************************************************************************
6947  Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
6948 ****************************************************************************/
6949
6950 static NTSTATUS smb2_file_rename_information(connection_struct *conn,
6951                                             struct smb_request *req,
6952                                             const char *pdata,
6953                                             int total_data,
6954                                             files_struct *fsp,
6955                                             struct smb_filename *smb_fname_src)
6956 {
6957         bool overwrite;
6958         uint32_t len;
6959         char *newname = NULL;
6960         struct smb_filename *smb_fname_dst = NULL;
6961         uint32_t ucf_flags = UCF_SAVE_LCOMP |
6962                 ucf_flags_from_smb_request(req);
6963         NTSTATUS status = NT_STATUS_OK;
6964         TALLOC_CTX *ctx = talloc_tos();
6965
6966         if (!fsp) {
6967                 return NT_STATUS_INVALID_HANDLE;
6968         }
6969
6970         if (total_data < 20) {
6971                 return NT_STATUS_INVALID_PARAMETER;
6972         }
6973
6974         overwrite = (CVAL(pdata,0) ? True : False);
6975         len = IVAL(pdata,16);
6976
6977         if (len > (total_data - 20) || (len == 0)) {
6978                 return NT_STATUS_INVALID_PARAMETER;
6979         }
6980
6981         if (req->posix_pathnames) {
6982                 srvstr_get_path_posix(ctx,
6983                                 pdata,
6984                                 req->flags2,
6985                                 &newname,
6986                                 &pdata[20],
6987                                 len,
6988                                 STR_TERMINATE,
6989                                 &status);
6990         } else {
6991                 srvstr_get_path(ctx,
6992                                 pdata,
6993                                 req->flags2,
6994                                 &newname,
6995                                 &pdata[20],
6996                                 len,
6997                                 STR_TERMINATE,
6998                                 &status);
6999         }
7000         if (!NT_STATUS_IS_OK(status)) {
7001                 return status;
7002         }
7003
7004         DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
7005                                 newname));
7006
7007         status = filename_convert(ctx,
7008                                 conn,
7009                                 newname,
7010                                 ucf_flags,
7011                                 NULL,
7012                                 NULL,
7013                                 &smb_fname_dst);
7014         if (!NT_STATUS_IS_OK(status)) {
7015                 return status;
7016         }
7017
7018         if (fsp->base_fsp) {
7019                 /* newname must be a stream name. */
7020                 if (newname[0] != ':') {
7021                         return NT_STATUS_NOT_SUPPORTED;
7022                 }
7023
7024                 /* Create an smb_fname to call rename_internals_fsp() with. */
7025                 smb_fname_dst = synthetic_smb_fname(talloc_tos(),
7026                                         fsp->base_fsp->fsp_name->base_name,
7027                                         newname,
7028                                         NULL,
7029                                         fsp->base_fsp->fsp_name->flags);
7030                 if (smb_fname_dst == NULL) {
7031                         status = NT_STATUS_NO_MEMORY;
7032                         goto out;
7033                 }
7034
7035                 /*
7036                  * Set the original last component, since
7037                  * rename_internals_fsp() requires it.
7038                  */
7039                 smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
7040                                                               newname);
7041                 if (smb_fname_dst->original_lcomp == NULL) {
7042                         status = NT_STATUS_NO_MEMORY;
7043                         goto out;
7044                 }
7045
7046         }
7047
7048         DEBUG(10,("smb2_file_rename_information: "
7049                   "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
7050                   fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
7051                   smb_fname_str_dbg(smb_fname_dst)));
7052         status = rename_internals_fsp(conn, fsp, smb_fname_dst,
7053                                 (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM),
7054                                 overwrite);
7055
7056  out:
7057         TALLOC_FREE(smb_fname_dst);
7058         return status;
7059 }
7060
7061 static NTSTATUS smb_file_link_information(connection_struct *conn,
7062                                             struct smb_request *req,
7063                                             const char *pdata,
7064                                             int total_data,
7065                                             files_struct *fsp,
7066                                             struct smb_filename *smb_fname_src)
7067 {
7068         bool overwrite;
7069         uint32_t len;
7070         char *newname = NULL;
7071         struct smb_filename *smb_fname_dst = NULL;
7072         NTSTATUS status = NT_STATUS_OK;
7073         uint32_t ucf_flags = UCF_SAVE_LCOMP |
7074                 ucf_flags_from_smb_request(req);
7075         TALLOC_CTX *ctx = talloc_tos();
7076
7077         if (!fsp) {
7078                 return NT_STATUS_INVALID_HANDLE;
7079         }
7080
7081         if (total_data < 20) {
7082                 return NT_STATUS_INVALID_PARAMETER;
7083         }
7084
7085         overwrite = (CVAL(pdata,0) ? true : false);
7086         len = IVAL(pdata,16);
7087
7088         if (len > (total_data - 20) || (len == 0)) {
7089                 return NT_STATUS_INVALID_PARAMETER;
7090         }
7091
7092         if (smb_fname_src->flags & SMB_FILENAME_POSIX_PATH) {
7093                 srvstr_get_path_posix(ctx,
7094                                 pdata,
7095                                 req->flags2,
7096                                 &newname,
7097                                 &pdata[20],
7098                                 len,
7099                                 STR_TERMINATE,
7100                                 &status);
7101                 ucf_flags |= UCF_POSIX_PATHNAMES;
7102         } else {
7103                 srvstr_get_path(ctx,
7104                                 pdata,
7105                                 req->flags2,
7106                                 &newname,
7107                                 &pdata[20],
7108                                 len,
7109                                 STR_TERMINATE,
7110                                 &status);
7111         }
7112         if (!NT_STATUS_IS_OK(status)) {
7113                 return status;
7114         }
7115
7116         DEBUG(10,("smb_file_link_information: got name |%s|\n",
7117                                 newname));
7118
7119         status = filename_convert(ctx,
7120                                 conn,
7121                                 newname,
7122                                 ucf_flags,
7123                                 NULL,
7124                                 NULL,
7125                                 &smb_fname_dst);
7126         if (!NT_STATUS_IS_OK(status)) {
7127                 return status;
7128         }
7129
7130         if (fsp->base_fsp) {
7131                 /* No stream names. */
7132                 return NT_STATUS_NOT_SUPPORTED;
7133         }
7134
7135         DEBUG(10,("smb_file_link_information: "
7136                   "SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
7137                   fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
7138                   smb_fname_str_dbg(smb_fname_dst)));
7139         status = hardlink_internals(ctx,
7140                                 conn,
7141                                 req,
7142                                 overwrite,
7143                                 fsp->fsp_name,
7144                                 smb_fname_dst);
7145
7146         TALLOC_FREE(smb_fname_dst);
7147         return status;
7148 }
7149
7150 /****************************************************************************
7151  Deal with SMB_FILE_RENAME_INFORMATION.
7152 ****************************************************************************/
7153
7154 static NTSTATUS smb_file_rename_information(connection_struct *conn,
7155                                             struct smb_request *req,
7156                                             const char *pdata,
7157                                             int total_data,
7158                                             files_struct *fsp,
7159                                             struct smb_filename *smb_fname_src)
7160 {
7161         bool overwrite;
7162         uint32_t root_fid;
7163         uint32_t len;
7164         char *newname = NULL;
7165         struct smb_filename *smb_fname_dst = NULL;
7166         bool dest_has_wcard = False;
7167         NTSTATUS status = NT_STATUS_OK;
7168         char *p;
7169         TALLOC_CTX *ctx = talloc_tos();
7170
7171         if (total_data < 13) {
7172                 return NT_STATUS_INVALID_PARAMETER;
7173         }
7174
7175         overwrite = (CVAL(pdata,0) ? True : False);
7176         root_fid = IVAL(pdata,4);
7177         len = IVAL(pdata,8);
7178
7179         if (len > (total_data - 12) || (len == 0) || (root_fid != 0)) {
7180                 return NT_STATUS_INVALID_PARAMETER;
7181         }
7182
7183         if (req->posix_pathnames) {
7184                 srvstr_get_path_wcard_posix(ctx,
7185                                 pdata,
7186                                 req->flags2,
7187                                 &newname,
7188                                 &pdata[12],
7189                                 len,
7190                                 0,
7191                                 &status,
7192                                 &dest_has_wcard);
7193         } else {
7194                 srvstr_get_path_wcard(ctx,
7195                                 pdata,
7196                                 req->flags2,
7197                                 &newname,
7198                                 &pdata[12],
7199                                 len,
7200                                 0,
7201                                 &status,
7202                                 &dest_has_wcard);
7203         }
7204         if (!NT_STATUS_IS_OK(status)) {
7205                 return status;
7206         }
7207
7208         DEBUG(10,("smb_file_rename_information: got name |%s|\n",
7209                                 newname));
7210
7211         if (req->flags2 & FLAGS2_DFS_PATHNAMES) {
7212                 status = resolve_dfspath_wcard(ctx, conn,
7213                                        newname,
7214                                        UCF_COND_ALLOW_WCARD_LCOMP,
7215                                        !conn->sconn->using_smb2,
7216                                        &newname,
7217                                        &dest_has_wcard);
7218                 if (!NT_STATUS_IS_OK(status)) {
7219                         return status;
7220                 }
7221         }
7222
7223         /* Check the new name has no '/' characters. */
7224         if (strchr_m(newname, '/')) {
7225                 return NT_STATUS_NOT_SUPPORTED;
7226         }
7227
7228         if (fsp && fsp->base_fsp) {
7229                 /* newname must be a stream name. */
7230                 if (newname[0] != ':') {
7231                         return NT_STATUS_NOT_SUPPORTED;
7232                 }
7233
7234                 /* Create an smb_fname to call rename_internals_fsp() with. */
7235                 smb_fname_dst = synthetic_smb_fname(talloc_tos(),
7236                                         fsp->base_fsp->fsp_name->base_name,
7237                                         newname,
7238                                         NULL,
7239                                         fsp->base_fsp->fsp_name->flags);
7240                 if (smb_fname_dst == NULL) {
7241                         status = NT_STATUS_NO_MEMORY;
7242                         goto out;
7243                 }
7244
7245                 /*
7246                  * Set the original last component, since
7247                  * rename_internals_fsp() requires it.
7248                  */
7249                 smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
7250                                                               newname);
7251                 if (smb_fname_dst->original_lcomp == NULL) {
7252                         status = NT_STATUS_NO_MEMORY;
7253                         goto out;
7254                 }
7255
7256         } else {
7257                 /*
7258                  * Build up an smb_fname_dst based on the filename passed in.
7259                  * We basically just strip off the last component, and put on
7260                  * the newname instead.
7261                  */
7262                 char *base_name = NULL;
7263                 uint32_t ucf_flags = UCF_SAVE_LCOMP |
7264                         ucf_flags_from_smb_request(req);
7265
7266                 if (dest_has_wcard) {
7267                         ucf_flags |= UCF_ALWAYS_ALLOW_WCARD_LCOMP;
7268                 }
7269
7270                 /* newname must *not* be a stream name. */
7271                 if (newname[0] == ':') {
7272                         return NT_STATUS_NOT_SUPPORTED;
7273                 }
7274
7275                 /*
7276                  * Strip off the last component (filename) of the path passed
7277                  * in.
7278                  */
7279                 base_name = talloc_strdup(ctx, smb_fname_src->base_name);
7280                 if (!base_name) {
7281                         return NT_STATUS_NO_MEMORY;
7282                 }
7283                 p = strrchr_m(base_name, '/');
7284                 if (p) {
7285                         p[1] = '\0';
7286                 } else {
7287                         base_name = talloc_strdup(ctx, "");
7288                         if (!base_name) {
7289                                 return NT_STATUS_NO_MEMORY;
7290                         }
7291                 }
7292                 /* Append the new name. */
7293                 base_name = talloc_asprintf_append(base_name,
7294                                 "%s",
7295                                 newname);
7296                 if (!base_name) {
7297                         return NT_STATUS_NO_MEMORY;
7298                 }
7299
7300                 status = unix_convert(ctx, conn, base_name, &smb_fname_dst,
7301                                         ucf_flags);
7302
7303                 /* If an error we expect this to be
7304                  * NT_STATUS_OBJECT_PATH_NOT_FOUND */
7305
7306                 if (!NT_STATUS_IS_OK(status)) {
7307                         if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND,
7308                                             status)) {
7309                                 goto out;
7310                         }
7311                         /* Create an smb_fname to call rename_internals_fsp() */
7312                         smb_fname_dst = synthetic_smb_fname(ctx,
7313                                                 base_name,
7314                                                 NULL,
7315                                                 NULL,
7316                                                 smb_fname_src->flags);
7317                         if (smb_fname_dst == NULL) {
7318                                 status = NT_STATUS_NO_MEMORY;
7319                                 goto out;
7320                         }
7321                 }
7322         }
7323
7324         if (fsp) {
7325                 DEBUG(10,("smb_file_rename_information: "
7326                           "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
7327                           fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
7328                           smb_fname_str_dbg(smb_fname_dst)));
7329                 status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
7330                                               overwrite);
7331         } else {
7332                 DEBUG(10,("smb_file_rename_information: "
7333                           "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
7334                           smb_fname_str_dbg(smb_fname_src),
7335                           smb_fname_str_dbg(smb_fname_dst)));
7336                 status = rename_internals(ctx, conn, req, smb_fname_src,
7337                                           smb_fname_dst, 0, overwrite, false,
7338                                           dest_has_wcard,
7339                                           FILE_WRITE_ATTRIBUTES);
7340         }
7341  out:
7342         TALLOC_FREE(smb_fname_dst);
7343         return status;
7344 }
7345
7346 /****************************************************************************
7347  Deal with SMB_SET_POSIX_ACL.
7348 ****************************************************************************/
7349
7350 #if defined(HAVE_POSIX_ACLS)
7351 static NTSTATUS smb_set_posix_acl(connection_struct *conn,
7352                                 struct smb_request *req,
7353                                 const char *pdata,
7354                                 int total_data_in,
7355                                 files_struct *fsp,
7356                                 const struct smb_filename *smb_fname)
7357 {
7358         uint16_t posix_acl_version;
7359         uint16_t num_file_acls;
7360         uint16_t num_def_acls;
7361         bool valid_file_acls = true;
7362         bool valid_def_acls = true;
7363         NTSTATUS status;
7364         unsigned int size_needed;
7365         unsigned int total_data;
7366         bool close_fsp = false;
7367
7368         if (total_data_in < 0) {
7369                 status = NT_STATUS_INVALID_PARAMETER;
7370                 goto out;
7371         }
7372
7373         total_data = total_data_in;
7374
7375         if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
7376                 status = NT_STATUS_INVALID_PARAMETER;
7377                 goto out;
7378         }
7379         posix_acl_version = SVAL(pdata,0);
7380         num_file_acls = SVAL(pdata,2);
7381         num_def_acls = SVAL(pdata,4);
7382
7383         if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
7384                 valid_file_acls = false;
7385                 num_file_acls = 0;
7386         }
7387
7388         if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
7389                 valid_def_acls = false;
7390                 num_def_acls = 0;
7391         }
7392
7393         if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
7394                 status = NT_STATUS_INVALID_PARAMETER;
7395                 goto out;
7396         }
7397
7398         /* Wrap checks. */
7399         if (num_file_acls + num_def_acls < num_file_acls) {
7400                 status = NT_STATUS_INVALID_PARAMETER;
7401                 goto out;
7402         }
7403
7404         size_needed = num_file_acls + num_def_acls;
7405
7406         /*
7407          * (size_needed * SMB_POSIX_ACL_ENTRY_SIZE) must be less
7408          * than UINT_MAX, so check by division.
7409          */
7410         if (size_needed > (UINT_MAX/SMB_POSIX_ACL_ENTRY_SIZE)) {
7411                 status = NT_STATUS_INVALID_PARAMETER;
7412                 goto out;
7413         }
7414
7415         size_needed = size_needed*SMB_POSIX_ACL_ENTRY_SIZE;
7416         if (size_needed + SMB_POSIX_ACL_HEADER_SIZE < size_needed) {
7417                 status = NT_STATUS_INVALID_PARAMETER;
7418                 goto out;
7419         }
7420         size_needed += SMB_POSIX_ACL_HEADER_SIZE;
7421
7422         if (total_data < size_needed) {
7423                 status = NT_STATUS_INVALID_PARAMETER;
7424                 goto out;
7425         }
7426
7427         /*
7428          * Ensure we always operate on a file descriptor, not just
7429          * the filename.
7430          */
7431         if (fsp == NULL) {
7432                 uint32_t access_mask = SEC_STD_WRITE_OWNER|
7433                                         SEC_STD_WRITE_DAC|
7434                                         SEC_STD_READ_CONTROL|
7435                                         FILE_READ_ATTRIBUTES|
7436                                         FILE_WRITE_ATTRIBUTES;
7437
7438                 status = get_posix_fsp(conn,
7439                                         req,
7440                                         smb_fname,
7441                                         access_mask,
7442                                         &fsp);
7443
7444                 if (!NT_STATUS_IS_OK(status)) {
7445                         goto out;
7446                 }
7447                 close_fsp = true;
7448         }
7449
7450         /* Here we know fsp != NULL */
7451         SMB_ASSERT(fsp != NULL);
7452
7453         status = refuse_symlink(conn, fsp, fsp->fsp_name);
7454         if (!NT_STATUS_IS_OK(status)) {
7455                 goto out;
7456         }
7457
7458         /* If we have a default acl, this *must* be a directory. */
7459         if (valid_def_acls && !fsp->is_directory) {
7460                 DBG_INFO("Can't set default acls on "
7461                          "non-directory %s\n",
7462                          fsp_str_dbg(fsp));
7463                 return NT_STATUS_INVALID_HANDLE;
7464         }
7465
7466         DBG_DEBUG("file %s num_file_acls = %"PRIu16", "
7467                   "num_def_acls = %"PRIu16"\n",
7468                   fsp_str_dbg(fsp),
7469                   num_file_acls,
7470                   num_def_acls);
7471
7472         /* Move pdata to the start of the file ACL entries. */
7473         pdata += SMB_POSIX_ACL_HEADER_SIZE;
7474
7475         if (valid_file_acls) {
7476                 status = set_unix_posix_acl(conn,
7477                                         fsp,
7478                                         num_file_acls,
7479                                         pdata);
7480                 if (!NT_STATUS_IS_OK(status)) {
7481                         goto out;
7482                 }
7483         }
7484
7485         /* Move pdata to the start of the default ACL entries. */
7486         pdata += (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE);
7487
7488         if (valid_def_acls) {
7489                 status = set_unix_posix_default_acl(conn,
7490                                         fsp,
7491                                         num_def_acls,
7492                                         pdata);
7493                 if (!NT_STATUS_IS_OK(status)) {
7494                         goto out;
7495                 }
7496         }
7497
7498         status = NT_STATUS_OK;
7499
7500   out:
7501
7502         if (close_fsp) {
7503                 (void)close_file(req, fsp, NORMAL_CLOSE);
7504                 fsp = NULL;
7505         }
7506         return status;
7507 }
7508 #endif
7509
7510 /****************************************************************************
7511  Deal with SMB_SET_POSIX_LOCK.
7512 ****************************************************************************/
7513
7514 static void smb_set_posix_lock_done(struct tevent_req *subreq);
7515
7516 static NTSTATUS smb_set_posix_lock(connection_struct *conn,
7517                                 struct smb_request *req,
7518                                 const char *pdata,
7519                                 int total_data,
7520                                 files_struct *fsp)
7521 {
7522         struct tevent_req *subreq = NULL;
7523         struct smbd_lock_element *lck = NULL;
7524         uint64_t count;
7525         uint64_t offset;
7526         uint64_t smblctx;
7527         bool blocking_lock = False;
7528         enum brl_type lock_type;
7529
7530         NTSTATUS status = NT_STATUS_OK;
7531
7532         if (fsp == NULL || fsp->fh->fd == -1) {
7533                 return NT_STATUS_INVALID_HANDLE;
7534         }
7535
7536         if (total_data != POSIX_LOCK_DATA_SIZE) {
7537                 return NT_STATUS_INVALID_PARAMETER;
7538         }
7539
7540         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
7541                 case POSIX_LOCK_TYPE_READ:
7542                         lock_type = READ_LOCK;
7543                         break;
7544                 case POSIX_LOCK_TYPE_WRITE:
7545                         /* Return the right POSIX-mappable error code for files opened read-only. */
7546                         if (!fsp->can_write) {
7547                                 return NT_STATUS_INVALID_HANDLE;
7548                         }
7549                         lock_type = WRITE_LOCK;
7550                         break;
7551                 case POSIX_LOCK_TYPE_UNLOCK:
7552                         lock_type = UNLOCK_LOCK;
7553                         break;
7554                 default:
7555                         return NT_STATUS_INVALID_PARAMETER;
7556         }
7557
7558         switch (SVAL(pdata, POSIX_LOCK_FLAGS_OFFSET)) {
7559         case POSIX_LOCK_FLAG_NOWAIT:
7560                 blocking_lock = false;
7561                 break;
7562         case POSIX_LOCK_FLAG_WAIT:
7563                 blocking_lock = true;
7564                 break;
7565         default:
7566                 return NT_STATUS_INVALID_PARAMETER;
7567         }
7568
7569         if (!lp_blocking_locks(SNUM(conn))) { 
7570                 blocking_lock = False;
7571         }
7572
7573         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
7574         offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
7575                         ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
7576         count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
7577                         ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
7578
7579         DBG_DEBUG("file %s, lock_type = %u, smblctx = %"PRIu64", "
7580                   "count = %"PRIu64", offset = %"PRIu64"\n",
7581                   fsp_str_dbg(fsp),
7582                   (unsigned int)lock_type,
7583                   smblctx,
7584                   count,
7585                   offset);
7586
7587         if (lock_type == UNLOCK_LOCK) {
7588                 struct smbd_lock_element l = {
7589                         .smblctx = smblctx,
7590                         .brltype = UNLOCK_LOCK,
7591                         .offset = offset,
7592                         .count = count,
7593                 };
7594                 status = smbd_do_unlocking(req, fsp, 1, &l, POSIX_LOCK);
7595                 return status;
7596         }
7597
7598         lck = talloc(req, struct smbd_lock_element);
7599         if (lck == NULL) {
7600                 return NT_STATUS_NO_MEMORY;
7601         }
7602
7603         *lck = (struct smbd_lock_element) {
7604                 .smblctx = smblctx,
7605                 .brltype = lock_type,
7606                 .count = count,
7607                 .offset = offset,
7608         };
7609
7610         subreq = smbd_smb1_do_locks_send(
7611                 fsp,
7612                 req->sconn->ev_ctx,
7613                 req->sconn->msg_ctx,
7614                 &req,
7615                 fsp,
7616                 blocking_lock ? UINT32_MAX : 0,
7617                 true,           /* large_offset */
7618                 POSIX_LOCK,
7619                 1,
7620                 lck);
7621         if (subreq == NULL) {
7622                 TALLOC_FREE(lck);
7623                 return NT_STATUS_NO_MEMORY;
7624         }
7625         tevent_req_set_callback(subreq, smb_set_posix_lock_done, req);
7626         return NT_STATUS_EVENT_PENDING;
7627 }
7628
7629 static void smb_set_posix_lock_done(struct tevent_req *subreq)
7630 {
7631         struct smb_request *req = NULL;
7632         NTSTATUS status;
7633         bool ok;
7634
7635         ok = smbd_smb1_do_locks_extract_smbreq(subreq, talloc_tos(), &req);
7636         SMB_ASSERT(ok);
7637
7638         status = smbd_smb1_do_locks_recv(subreq);
7639         TALLOC_FREE(subreq);
7640
7641         if (NT_STATUS_IS_OK(status)) {
7642                 char params[2] = {0};
7643                 /* Fake up max_data_bytes here - we know it fits. */
7644                 send_trans2_replies(
7645                         req->conn,
7646                         req,
7647                         NT_STATUS_OK,
7648                         params,
7649                         2,
7650                         NULL,
7651                         0,
7652                         0xffff);
7653         } else {
7654                 reply_nterror(req, status);
7655                 ok = srv_send_smb(
7656                         req->xconn,
7657                         (char *)req->outbuf,
7658                         true,
7659                         req->seqnum+1,
7660                         IS_CONN_ENCRYPTED(req->conn),
7661                         NULL);
7662                 if (!ok) {
7663                         exit_server_cleanly("smb_set_posix_lock_done: "
7664                                             "srv_send_smb failed.");
7665                 }
7666         }
7667
7668         TALLOC_FREE(req);
7669         return;
7670 }
7671
7672 /****************************************************************************
7673  Deal with SMB_SET_FILE_BASIC_INFO.
7674 ****************************************************************************/
7675
7676 static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
7677                                         const char *pdata,
7678                                         int total_data,
7679                                         files_struct *fsp,
7680                                         const struct smb_filename *smb_fname)
7681 {
7682         /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
7683         struct smb_file_time ft;
7684         uint32_t dosmode = 0;
7685         NTSTATUS status = NT_STATUS_OK;
7686
7687         ZERO_STRUCT(ft);
7688
7689         if (total_data < 36) {
7690                 return NT_STATUS_INVALID_PARAMETER;
7691         }
7692
7693         status = check_access(conn, fsp, smb_fname, FILE_WRITE_ATTRIBUTES);
7694         if (!NT_STATUS_IS_OK(status)) {
7695                 return status;
7696         }
7697
7698         /* Set the attributes */
7699         dosmode = IVAL(pdata,32);
7700         status = smb_set_file_dosmode(conn, smb_fname, dosmode);
7701         if (!NT_STATUS_IS_OK(status)) {
7702                 return status;
7703         }
7704
7705         /* create time */
7706         ft.create_time = interpret_long_date(pdata);
7707
7708         /* access time */
7709         ft.atime = interpret_long_date(pdata+8);
7710
7711         /* write time. */
7712         ft.mtime = interpret_long_date(pdata+16);
7713
7714         /* change time. */
7715         ft.ctime = interpret_long_date(pdata+24);
7716
7717         DEBUG(10, ("smb_set_file_basic_info: file %s\n",
7718                    smb_fname_str_dbg(smb_fname)));
7719
7720         return smb_set_file_time(conn, fsp, smb_fname, &ft,
7721                                  true);
7722 }
7723
7724 /****************************************************************************
7725  Deal with SMB_INFO_STANDARD.
7726 ****************************************************************************/
7727
7728 static NTSTATUS smb_set_info_standard(connection_struct *conn,
7729                                         const char *pdata,
7730                                         int total_data,
7731                                         files_struct *fsp,
7732                                         const struct smb_filename *smb_fname)
7733 {
7734         NTSTATUS status;
7735         struct smb_file_time ft;
7736
7737         ZERO_STRUCT(ft);
7738
7739         if (total_data < 12) {
7740                 return NT_STATUS_INVALID_PARAMETER;
7741         }
7742
7743         /* create time */
7744         ft.create_time = convert_time_t_to_timespec(srv_make_unix_date2(pdata));
7745         /* access time */
7746         ft.atime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+4));
7747         /* write time */
7748         ft.mtime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+8));
7749
7750         DEBUG(10,("smb_set_info_standard: file %s\n",
7751                 smb_fname_str_dbg(smb_fname)));
7752
7753         status = check_access(conn, fsp, smb_fname, FILE_WRITE_ATTRIBUTES);
7754         if (!NT_STATUS_IS_OK(status)) {
7755                 return status;
7756         }
7757
7758         return smb_set_file_time(conn,
7759                                 fsp,
7760                                 smb_fname,
7761                                 &ft,
7762                                 true);
7763 }
7764
7765 /****************************************************************************
7766  Deal with SMB_SET_FILE_ALLOCATION_INFO.
7767 ****************************************************************************/
7768
7769 static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
7770                                              struct smb_request *req,
7771                                         const char *pdata,
7772                                         int total_data,
7773                                         files_struct *fsp,
7774                                         struct smb_filename *smb_fname)
7775 {
7776         uint64_t allocation_size = 0;
7777         NTSTATUS status = NT_STATUS_OK;
7778         files_struct *new_fsp = NULL;
7779
7780         if (!VALID_STAT(smb_fname->st)) {
7781                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
7782         }
7783
7784         if (total_data < 8) {
7785                 return NT_STATUS_INVALID_PARAMETER;
7786         }
7787
7788         allocation_size = (uint64_t)IVAL(pdata,0);
7789         allocation_size |= (((uint64_t)IVAL(pdata,4)) << 32);
7790         DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
7791                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
7792                   (double)allocation_size));
7793
7794         if (allocation_size) {
7795                 allocation_size = smb_roundup(conn, allocation_size);
7796         }
7797
7798         DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
7799                   "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname),
7800                   (double)allocation_size));
7801
7802         if (fsp && fsp->fh->fd != -1) {
7803                 /* Open file handle. */
7804                 if (!(fsp->access_mask & FILE_WRITE_DATA)) {
7805                         return NT_STATUS_ACCESS_DENIED;
7806                 }
7807
7808                 /* Only change if needed. */
7809                 if (allocation_size != get_file_size_stat(&smb_fname->st)) {
7810                         if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
7811                                 return map_nt_error_from_unix(errno);
7812                         }
7813                 }
7814                 /* But always update the time. */
7815                 /*
7816                  * This is equivalent to a write. Ensure it's seen immediately
7817                  * if there are no pending writes.
7818                  */
7819                 trigger_write_time_update_immediate(fsp);
7820                 return NT_STATUS_OK;
7821         }
7822
7823         /* Pathname or stat or directory file. */
7824         status = SMB_VFS_CREATE_FILE(
7825                 conn,                                   /* conn */
7826                 req,                                    /* req */
7827                 0,                                      /* root_dir_fid */
7828                 smb_fname,                              /* fname */
7829                 FILE_WRITE_DATA,                        /* access_mask */
7830                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
7831                     FILE_SHARE_DELETE),
7832                 FILE_OPEN,                              /* create_disposition*/
7833                 0,                                      /* create_options */
7834                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
7835                 0,                                      /* oplock_request */
7836                 NULL,                                   /* lease */
7837                 0,                                      /* allocation_size */
7838                 0,                                      /* private_flags */
7839                 NULL,                                   /* sd */
7840                 NULL,                                   /* ea_list */
7841                 &new_fsp,                               /* result */
7842                 NULL,                                   /* pinfo */
7843                 NULL, NULL);                            /* create context */
7844
7845         if (!NT_STATUS_IS_OK(status)) {
7846                 /* NB. We check for open_was_deferred in the caller. */
7847                 return status;
7848         }
7849
7850         /* Only change if needed. */
7851         if (allocation_size != get_file_size_stat(&smb_fname->st)) {
7852                 if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
7853                         status = map_nt_error_from_unix(errno);
7854                         close_file(req, new_fsp, NORMAL_CLOSE);
7855                         return status;
7856                 }
7857         }
7858
7859         /* Changing the allocation size should set the last mod time. */
7860         /*
7861          * This is equivalent to a write. Ensure it's seen immediately
7862          * if there are no pending writes.
7863          */
7864         trigger_write_time_update_immediate(new_fsp);
7865         close_file(req, new_fsp, NORMAL_CLOSE);
7866         return NT_STATUS_OK;
7867 }
7868
7869 /****************************************************************************
7870  Deal with SMB_SET_FILE_END_OF_FILE_INFO.
7871 ****************************************************************************/
7872
7873 static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
7874                                               struct smb_request *req,
7875                                         const char *pdata,
7876                                         int total_data,
7877                                         files_struct *fsp,
7878                                         const struct smb_filename *smb_fname,
7879                                         bool fail_after_createfile)
7880 {
7881         off_t size;
7882
7883         if (total_data < 8) {
7884                 return NT_STATUS_INVALID_PARAMETER;
7885         }
7886
7887         size = IVAL(pdata,0);
7888         size |= (((off_t)IVAL(pdata,4)) << 32);
7889         DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
7890                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
7891                   (double)size));
7892
7893         return smb_set_file_size(conn, req,
7894                                 fsp,
7895                                 smb_fname,
7896                                 &smb_fname->st,
7897                                 size,
7898                                 fail_after_createfile);
7899 }
7900
7901 /****************************************************************************
7902  Allow a UNIX info mknod.
7903 ****************************************************************************/
7904
7905 static NTSTATUS smb_unix_mknod(connection_struct *conn,
7906                                         const char *pdata,
7907                                         int total_data,
7908                                         const struct smb_filename *smb_fname)
7909 {
7910         uint32_t file_type = IVAL(pdata,56);
7911 #if defined(HAVE_MAKEDEV)
7912         uint32_t dev_major = IVAL(pdata,60);
7913         uint32_t dev_minor = IVAL(pdata,68);
7914 #endif
7915         SMB_DEV_T dev = (SMB_DEV_T)0;
7916         uint32_t raw_unixmode = IVAL(pdata,84);
7917         NTSTATUS status;
7918         mode_t unixmode;
7919
7920         if (total_data < 100) {
7921                 return NT_STATUS_INVALID_PARAMETER;
7922         }
7923
7924         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
7925                                       PERM_NEW_FILE, &unixmode);
7926         if (!NT_STATUS_IS_OK(status)) {
7927                 return status;
7928         }
7929
7930 #if defined(HAVE_MAKEDEV)
7931         dev = makedev(dev_major, dev_minor);
7932 #endif
7933
7934         switch (file_type) {
7935 #if defined(S_IFIFO)
7936                 case UNIX_TYPE_FIFO:
7937                         unixmode |= S_IFIFO;
7938                         break;
7939 #endif
7940 #if defined(S_IFSOCK)
7941                 case UNIX_TYPE_SOCKET:
7942                         unixmode |= S_IFSOCK;
7943                         break;
7944 #endif
7945 #if defined(S_IFCHR)
7946                 case UNIX_TYPE_CHARDEV:
7947                         unixmode |= S_IFCHR;
7948                         break;
7949 #endif
7950 #if defined(S_IFBLK)
7951                 case UNIX_TYPE_BLKDEV:
7952                         unixmode |= S_IFBLK;
7953                         break;
7954 #endif
7955                 default:
7956                         return NT_STATUS_INVALID_PARAMETER;
7957         }
7958
7959         DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
7960                   "%.0f mode 0%o for file %s\n", (double)dev,
7961                   (unsigned int)unixmode, smb_fname_str_dbg(smb_fname)));
7962
7963         /* Ok - do the mknod. */
7964         if (SMB_VFS_MKNOD(conn, smb_fname, unixmode, dev) != 0) {
7965                 return map_nt_error_from_unix(errno);
7966         }
7967
7968         /* If any of the other "set" calls fail we
7969          * don't want to end up with a half-constructed mknod.
7970          */
7971
7972         if (lp_inherit_permissions(SNUM(conn))) {
7973                 char *parent;
7974                 if (!parent_dirname(talloc_tos(), smb_fname->base_name,
7975                                     &parent, NULL)) {
7976                         return NT_STATUS_NO_MEMORY;
7977                 }
7978                 inherit_access_posix_acl(conn, parent, smb_fname,
7979                                          unixmode);
7980                 TALLOC_FREE(parent);
7981         }
7982
7983         return NT_STATUS_OK;
7984 }
7985
7986 /****************************************************************************
7987  Deal with SMB_SET_FILE_UNIX_BASIC.
7988 ****************************************************************************/
7989
7990 static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
7991                                         struct smb_request *req,
7992                                         const char *pdata,
7993                                         int total_data,
7994                                         files_struct *fsp,
7995                                         const struct smb_filename *smb_fname)
7996 {
7997         struct smb_file_time ft;
7998         uint32_t raw_unixmode;
7999         mode_t unixmode;
8000         off_t size = 0;
8001         uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
8002         gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
8003         NTSTATUS status = NT_STATUS_OK;
8004         bool delete_on_fail = False;
8005         enum perm_type ptype;
8006         files_struct *all_fsps = NULL;
8007         bool modify_mtime = true;
8008         struct file_id id;
8009         struct smb_filename *smb_fname_tmp = NULL;
8010         SMB_STRUCT_STAT sbuf;
8011
8012         ZERO_STRUCT(ft);
8013
8014         if (total_data < 100) {
8015                 return NT_STATUS_INVALID_PARAMETER;
8016         }
8017
8018         if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
8019            IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
8020                 size=IVAL(pdata,0); /* first 8 Bytes are size */
8021                 size |= (((off_t)IVAL(pdata,4)) << 32);
8022         }
8023
8024         ft.atime = interpret_long_date(pdata+24); /* access_time */
8025         ft.mtime = interpret_long_date(pdata+32); /* modification_time */
8026         set_owner = (uid_t)IVAL(pdata,40);
8027         set_grp = (gid_t)IVAL(pdata,48);
8028         raw_unixmode = IVAL(pdata,84);
8029
8030         if (VALID_STAT(smb_fname->st)) {
8031                 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
8032                         ptype = PERM_EXISTING_DIR;
8033                 } else {
8034                         ptype = PERM_EXISTING_FILE;
8035                 }
8036         } else {
8037                 ptype = PERM_NEW_FILE;
8038         }
8039
8040         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8041                                       ptype, &unixmode);
8042         if (!NT_STATUS_IS_OK(status)) {
8043                 return status;
8044         }
8045
8046         DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
8047                   "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
8048                   smb_fname_str_dbg(smb_fname), (double)size,
8049                   (unsigned int)set_owner, (unsigned int)set_grp,
8050                   (int)raw_unixmode));
8051
8052         sbuf = smb_fname->st;
8053
8054         if (!VALID_STAT(sbuf)) {
8055                 /*
8056                  * The only valid use of this is to create character and block
8057                  * devices, and named pipes. This is deprecated (IMHO) and 
8058                  * a new info level should be used for mknod. JRA.
8059                  */
8060
8061                 status = smb_unix_mknod(conn,
8062                                         pdata,
8063                                         total_data,
8064                                         smb_fname);
8065                 if (!NT_STATUS_IS_OK(status)) {
8066                         return status;
8067                 }
8068
8069                 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
8070                 if (smb_fname_tmp == NULL) {
8071                         return NT_STATUS_NO_MEMORY;
8072                 }
8073
8074                 if (SMB_VFS_STAT(conn, smb_fname_tmp) != 0) {
8075                         status = map_nt_error_from_unix(errno);
8076                         TALLOC_FREE(smb_fname_tmp);
8077                         SMB_VFS_UNLINK(conn, smb_fname);
8078                         return status;
8079                 }
8080
8081                 sbuf = smb_fname_tmp->st;
8082                 smb_fname = smb_fname_tmp;
8083
8084                 /* Ensure we don't try and change anything else. */
8085                 raw_unixmode = SMB_MODE_NO_CHANGE;
8086                 size = get_file_size_stat(&sbuf);
8087                 ft.atime = sbuf.st_ex_atime;
8088                 ft.mtime = sbuf.st_ex_mtime;
8089                 /* 
8090                  * We continue here as we might want to change the 
8091                  * owner uid/gid.
8092                  */
8093                 delete_on_fail = True;
8094         }
8095
8096 #if 1
8097         /* Horrible backwards compatibility hack as an old server bug
8098          * allowed a CIFS client bug to remain unnoticed :-(. JRA.
8099          * */
8100
8101         if (!size) {
8102                 size = get_file_size_stat(&sbuf);
8103         }
8104 #endif
8105
8106         /*
8107          * Deal with the UNIX specific mode set.
8108          */
8109
8110         if (raw_unixmode != SMB_MODE_NO_CHANGE) {
8111                 int ret;
8112
8113                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
8114                           "setting mode 0%o for file %s\n",
8115                           (unsigned int)unixmode,
8116                           smb_fname_str_dbg(smb_fname)));
8117                 if (fsp && fsp->fh->fd != -1) {
8118                         ret = SMB_VFS_FCHMOD(fsp, unixmode);
8119                 } else {
8120                         ret = SMB_VFS_CHMOD(conn, smb_fname, unixmode);
8121                 }
8122                 if (ret != 0) {
8123                         return map_nt_error_from_unix(errno);
8124                 }
8125         }
8126
8127         /*
8128          * Deal with the UNIX specific uid set.
8129          */
8130
8131         if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) &&
8132             (sbuf.st_ex_uid != set_owner)) {
8133                 int ret;
8134
8135                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
8136                           "changing owner %u for path %s\n",
8137                           (unsigned int)set_owner,
8138                           smb_fname_str_dbg(smb_fname)));
8139
8140                 if (fsp && fsp->fh->fd != -1) {
8141                         ret = SMB_VFS_FCHOWN(fsp, set_owner, (gid_t)-1);
8142                 } else {
8143                         /*
8144                          * UNIX extensions calls must always operate
8145                          * on symlinks.
8146                          */
8147                         ret = SMB_VFS_LCHOWN(conn, smb_fname,
8148                                              set_owner, (gid_t)-1);
8149                 }
8150
8151                 if (ret != 0) {
8152                         status = map_nt_error_from_unix(errno);
8153                         if (delete_on_fail) {
8154                                 SMB_VFS_UNLINK(conn, smb_fname);
8155                         }
8156                         return status;
8157                 }
8158         }
8159
8160         /*
8161          * Deal with the UNIX specific gid set.
8162          */
8163
8164         if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) &&
8165             (sbuf.st_ex_gid != set_grp)) {
8166                 int ret;
8167
8168                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
8169                           "changing group %u for file %s\n",
8170                           (unsigned int)set_grp,
8171                           smb_fname_str_dbg(smb_fname)));
8172                 if (fsp && fsp->fh->fd != -1) {
8173                         ret = SMB_VFS_FCHOWN(fsp, (uid_t)-1, set_grp);
8174                 } else {
8175                         /*
8176                          * UNIX extensions calls must always operate
8177                          * on symlinks.
8178                          */
8179                         ret = SMB_VFS_LCHOWN(conn, smb_fname, (uid_t)-1,
8180                                   set_grp);
8181                 }
8182                 if (ret != 0) {
8183                         status = map_nt_error_from_unix(errno);
8184                         if (delete_on_fail) {
8185                                 SMB_VFS_UNLINK(conn, smb_fname);
8186                         }
8187                         return status;
8188                 }
8189         }
8190
8191         /* Deal with any size changes. */
8192
8193         status = smb_set_file_size(conn, req,
8194                                    fsp,
8195                                    smb_fname,
8196                                    &sbuf,
8197                                    size,
8198                                    false);
8199         if (!NT_STATUS_IS_OK(status)) {
8200                 return status;
8201         }
8202
8203         /* Deal with any time changes. */
8204         if (null_timespec(ft.mtime) && null_timespec(ft.atime)) {
8205                 /* No change, don't cancel anything. */
8206                 return status;
8207         }
8208
8209         id = vfs_file_id_from_sbuf(conn, &sbuf);
8210         for(all_fsps = file_find_di_first(conn->sconn, id); all_fsps;
8211                         all_fsps = file_find_di_next(all_fsps)) {
8212                 /*
8213                  * We're setting the time explicitly for UNIX.
8214                  * Cancel any pending changes over all handles.
8215                  */
8216                 all_fsps->update_write_time_on_close = false;
8217                 TALLOC_FREE(all_fsps->update_write_time_event);
8218         }
8219
8220         /*
8221          * Override the "setting_write_time"
8222          * parameter here as it almost does what
8223          * we need. Just remember if we modified
8224          * mtime and send the notify ourselves.
8225          */
8226         if (null_timespec(ft.mtime)) {
8227                 modify_mtime = false;
8228         }
8229
8230         status = smb_set_file_time(conn,
8231                                 fsp,
8232                                 smb_fname,
8233                                 &ft,
8234                                 false);
8235         if (modify_mtime) {
8236                 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
8237                         FILE_NOTIFY_CHANGE_LAST_WRITE, smb_fname->base_name);
8238         }
8239         return status;
8240 }
8241
8242 /****************************************************************************
8243  Deal with SMB_SET_FILE_UNIX_INFO2.
8244 ****************************************************************************/
8245
8246 static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
8247                                         struct smb_request *req,
8248                                         const char *pdata,
8249                                         int total_data,
8250                                         files_struct *fsp,
8251                                         const struct smb_filename *smb_fname)
8252 {
8253         NTSTATUS status;
8254         uint32_t smb_fflags;
8255         uint32_t smb_fmask;
8256
8257         if (total_data < 116) {
8258                 return NT_STATUS_INVALID_PARAMETER;
8259         }
8260
8261         /* Start by setting all the fields that are common between UNIX_BASIC
8262          * and UNIX_INFO2.
8263          */
8264         status = smb_set_file_unix_basic(conn, req, pdata, total_data,
8265                                          fsp, smb_fname);
8266         if (!NT_STATUS_IS_OK(status)) {
8267                 return status;
8268         }
8269
8270         smb_fflags = IVAL(pdata, 108);
8271         smb_fmask = IVAL(pdata, 112);
8272
8273         /* NB: We should only attempt to alter the file flags if the client
8274          * sends a non-zero mask.
8275          */
8276         if (smb_fmask != 0) {
8277                 int stat_fflags = 0;
8278
8279                 if (!map_info2_flags_to_sbuf(&smb_fname->st, smb_fflags,
8280                                              smb_fmask, &stat_fflags)) {
8281                         /* Client asked to alter a flag we don't understand. */
8282                         return NT_STATUS_INVALID_PARAMETER;
8283                 }
8284
8285                 if (fsp && fsp->fh->fd != -1) {
8286                         /* XXX: we should be  using SMB_VFS_FCHFLAGS here. */
8287                         return NT_STATUS_NOT_SUPPORTED;
8288                 } else {
8289                         if (SMB_VFS_CHFLAGS(conn, smb_fname,
8290                                             stat_fflags) != 0) {
8291                                 return map_nt_error_from_unix(errno);
8292                         }
8293                 }
8294         }
8295
8296         /* XXX: need to add support for changing the create_time here. You
8297          * can do this for paths on Darwin with setattrlist(2). The right way
8298          * to hook this up is probably by extending the VFS utimes interface.
8299          */
8300
8301         return NT_STATUS_OK;
8302 }
8303
8304 /****************************************************************************
8305  Create a directory with POSIX semantics.
8306 ****************************************************************************/
8307
8308 static NTSTATUS smb_posix_mkdir(connection_struct *conn,
8309                                 struct smb_request *req,
8310                                 char **ppdata,
8311                                 int total_data,
8312                                 struct smb_filename *smb_fname,
8313                                 int *pdata_return_size)
8314 {
8315         NTSTATUS status = NT_STATUS_OK;
8316         uint32_t raw_unixmode = 0;
8317         uint32_t mod_unixmode = 0;
8318         mode_t unixmode = (mode_t)0;
8319         files_struct *fsp = NULL;
8320         uint16_t info_level_return = 0;
8321         int info;
8322         char *pdata = *ppdata;
8323
8324         if (total_data < 18) {
8325                 return NT_STATUS_INVALID_PARAMETER;
8326         }
8327
8328         raw_unixmode = IVAL(pdata,8);
8329         /* Next 4 bytes are not yet defined. */
8330
8331         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8332                                       PERM_NEW_DIR, &unixmode);
8333         if (!NT_STATUS_IS_OK(status)) {
8334                 return status;
8335         }
8336
8337         mod_unixmode = (uint32_t)unixmode | FILE_FLAG_POSIX_SEMANTICS;
8338
8339         DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
8340                   smb_fname_str_dbg(smb_fname), (unsigned int)unixmode));
8341
8342         status = SMB_VFS_CREATE_FILE(
8343                 conn,                                   /* conn */
8344                 req,                                    /* req */
8345                 0,                                      /* root_dir_fid */
8346                 smb_fname,                              /* fname */
8347                 FILE_READ_ATTRIBUTES,                   /* access_mask */
8348                 FILE_SHARE_NONE,                        /* share_access */
8349                 FILE_CREATE,                            /* create_disposition*/
8350                 FILE_DIRECTORY_FILE,                    /* create_options */
8351                 mod_unixmode,                           /* file_attributes */
8352                 0,                                      /* oplock_request */
8353                 NULL,                                   /* lease */
8354                 0,                                      /* allocation_size */
8355                 0,                                      /* private_flags */
8356                 NULL,                                   /* sd */
8357                 NULL,                                   /* ea_list */
8358                 &fsp,                                   /* result */
8359                 &info,                                  /* pinfo */
8360                 NULL, NULL);                            /* create context */
8361
8362         if (NT_STATUS_IS_OK(status)) {
8363                 close_file(req, fsp, NORMAL_CLOSE);
8364         }
8365
8366         info_level_return = SVAL(pdata,16);
8367  
8368         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
8369                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
8370         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
8371                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
8372         } else {
8373                 *pdata_return_size = 12;
8374         }
8375
8376         /* Realloc the data size */
8377         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
8378         if (*ppdata == NULL) {
8379                 *pdata_return_size = 0;
8380                 return NT_STATUS_NO_MEMORY;
8381         }
8382         pdata = *ppdata;
8383
8384         SSVAL(pdata,0,NO_OPLOCK_RETURN);
8385         SSVAL(pdata,2,0); /* No fnum. */
8386         SIVAL(pdata,4,info); /* Was directory created. */
8387
8388         switch (info_level_return) {
8389                 case SMB_QUERY_FILE_UNIX_BASIC:
8390                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
8391                         SSVAL(pdata,10,0); /* Padding. */
8392                         store_file_unix_basic(conn, pdata + 12, fsp,
8393                                               &smb_fname->st);
8394                         break;
8395                 case SMB_QUERY_FILE_UNIX_INFO2:
8396                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
8397                         SSVAL(pdata,10,0); /* Padding. */
8398                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
8399                                                     &smb_fname->st);
8400                         break;
8401                 default:
8402                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
8403                         SSVAL(pdata,10,0); /* Padding. */
8404                         break;
8405         }
8406
8407         return status;
8408 }
8409
8410 /****************************************************************************
8411  Open/Create a file with POSIX semantics.
8412 ****************************************************************************/
8413
8414 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
8415 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
8416
8417 static NTSTATUS smb_posix_open(connection_struct *conn,
8418                                struct smb_request *req,
8419                                 char **ppdata,
8420                                 int total_data,
8421                                 struct smb_filename *smb_fname,
8422                                 int *pdata_return_size)
8423 {
8424         bool extended_oplock_granted = False;
8425         char *pdata = *ppdata;
8426         uint32_t flags = 0;
8427         uint32_t wire_open_mode = 0;
8428         uint32_t raw_unixmode = 0;
8429         uint32_t mod_unixmode = 0;
8430         uint32_t create_disp = 0;
8431         uint32_t access_mask = 0;
8432         uint32_t create_options = FILE_NON_DIRECTORY_FILE;
8433         NTSTATUS status = NT_STATUS_OK;
8434         mode_t unixmode = (mode_t)0;
8435         files_struct *fsp = NULL;
8436         int oplock_request = 0;
8437         int info = 0;
8438         uint16_t info_level_return = 0;
8439
8440         if (total_data < 18) {
8441                 return NT_STATUS_INVALID_PARAMETER;
8442         }
8443
8444         flags = IVAL(pdata,0);
8445         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
8446         if (oplock_request) {
8447                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
8448         }
8449
8450         wire_open_mode = IVAL(pdata,4);
8451
8452         if (wire_open_mode == (SMB_O_CREAT|SMB_O_DIRECTORY)) {
8453                 return smb_posix_mkdir(conn, req,
8454                                         ppdata,
8455                                         total_data,
8456                                         smb_fname,
8457                                         pdata_return_size);
8458         }
8459
8460         switch (wire_open_mode & SMB_ACCMODE) {
8461                 case SMB_O_RDONLY:
8462                         access_mask = SMB_O_RDONLY_MAPPING;
8463                         break;
8464                 case SMB_O_WRONLY:
8465                         access_mask = SMB_O_WRONLY_MAPPING;
8466                         break;
8467                 case SMB_O_RDWR:
8468                         access_mask = (SMB_O_RDONLY_MAPPING|
8469                                         SMB_O_WRONLY_MAPPING);
8470                         break;
8471                 default:
8472                         DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
8473                                 (unsigned int)wire_open_mode ));
8474                         return NT_STATUS_INVALID_PARAMETER;
8475         }
8476
8477         wire_open_mode &= ~SMB_ACCMODE;
8478
8479         /* First take care of O_CREAT|O_EXCL interactions. */
8480         switch (wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) {
8481                 case (SMB_O_CREAT | SMB_O_EXCL):
8482                         /* File exists fail. File not exist create. */
8483                         create_disp = FILE_CREATE;
8484                         break;
8485                 case SMB_O_CREAT:
8486                         /* File exists open. File not exist create. */
8487                         create_disp = FILE_OPEN_IF;
8488                         break;
8489                 case SMB_O_EXCL:
8490                         /* O_EXCL on its own without O_CREAT is undefined.
8491                            We deliberately ignore it as some versions of
8492                            Linux CIFSFS can send a bare O_EXCL on the
8493                            wire which other filesystems in the kernel
8494                            ignore. See bug 9519 for details. */
8495
8496                         /* Fallthrough. */
8497
8498                 case 0:
8499                         /* File exists open. File not exist fail. */
8500                         create_disp = FILE_OPEN;
8501                         break;
8502                 default:
8503                         DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
8504                                 (unsigned int)wire_open_mode ));
8505                         return NT_STATUS_INVALID_PARAMETER;
8506         }
8507
8508         /* Next factor in the effects of O_TRUNC. */
8509         wire_open_mode &= ~(SMB_O_CREAT | SMB_O_EXCL);
8510
8511         if (wire_open_mode & SMB_O_TRUNC) {
8512                 switch (create_disp) {
8513                         case FILE_CREATE:
8514                                 /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
8515                                 /* Leave create_disp alone as
8516                                    (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
8517                                 */
8518                                 /* File exists fail. File not exist create. */
8519                                 break;
8520                         case FILE_OPEN_IF:
8521                                 /* SMB_O_CREAT | SMB_O_TRUNC */
8522                                 /* File exists overwrite. File not exist create. */
8523                                 create_disp = FILE_OVERWRITE_IF;
8524                                 break;
8525                         case FILE_OPEN:
8526                                 /* SMB_O_TRUNC */
8527                                 /* File exists overwrite. File not exist fail. */
8528                                 create_disp = FILE_OVERWRITE;
8529                                 break;
8530                         default:
8531                                 /* Cannot get here. */
8532                                 smb_panic("smb_posix_open: logic error");
8533                                 return NT_STATUS_INVALID_PARAMETER;
8534                 }
8535         }
8536
8537         raw_unixmode = IVAL(pdata,8);
8538         /* Next 4 bytes are not yet defined. */
8539
8540         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8541                                       (VALID_STAT(smb_fname->st) ?
8542                                           PERM_EXISTING_FILE : PERM_NEW_FILE),
8543                                       &unixmode);
8544
8545         if (!NT_STATUS_IS_OK(status)) {
8546                 return status;
8547         }
8548
8549         mod_unixmode = (uint32_t)unixmode | FILE_FLAG_POSIX_SEMANTICS;
8550
8551         if (wire_open_mode & SMB_O_SYNC) {
8552                 create_options |= FILE_WRITE_THROUGH;
8553         }
8554         if (wire_open_mode & SMB_O_APPEND) {
8555                 access_mask |= FILE_APPEND_DATA;
8556         }
8557         if (wire_open_mode & SMB_O_DIRECT) {
8558                 mod_unixmode |= FILE_FLAG_NO_BUFFERING;
8559         }
8560
8561         if ((wire_open_mode & SMB_O_DIRECTORY) ||
8562                         VALID_STAT_OF_DIR(smb_fname->st)) {
8563                 if (access_mask != SMB_O_RDONLY_MAPPING) {
8564                         return NT_STATUS_FILE_IS_A_DIRECTORY;
8565                 }
8566                 create_options &= ~FILE_NON_DIRECTORY_FILE;
8567                 create_options |= FILE_DIRECTORY_FILE;
8568         }
8569
8570         DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
8571                 smb_fname_str_dbg(smb_fname),
8572                 (unsigned int)wire_open_mode,
8573                 (unsigned int)unixmode ));
8574
8575         status = SMB_VFS_CREATE_FILE(
8576                 conn,                                   /* conn */
8577                 req,                                    /* req */
8578                 0,                                      /* root_dir_fid */
8579                 smb_fname,                              /* fname */
8580                 access_mask,                            /* access_mask */
8581                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
8582                     FILE_SHARE_DELETE),
8583                 create_disp,                            /* create_disposition*/
8584                 create_options,                         /* create_options */
8585                 mod_unixmode,                           /* file_attributes */
8586                 oplock_request,                         /* oplock_request */
8587                 NULL,                                   /* lease */
8588                 0,                                      /* allocation_size */
8589                 0,                                      /* private_flags */
8590                 NULL,                                   /* sd */
8591                 NULL,                                   /* ea_list */
8592                 &fsp,                                   /* result */
8593                 &info,                                  /* pinfo */
8594                 NULL, NULL);                            /* create context */
8595
8596         if (!NT_STATUS_IS_OK(status)) {
8597                 return status;
8598         }
8599
8600         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
8601                 extended_oplock_granted = True;
8602         }
8603
8604         if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
8605                 extended_oplock_granted = True;
8606         }
8607
8608         info_level_return = SVAL(pdata,16);
8609  
8610         /* Allocate the correct return size. */
8611
8612         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
8613                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
8614         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
8615                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
8616         } else {
8617                 *pdata_return_size = 12;
8618         }
8619
8620         /* Realloc the data size */
8621         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
8622         if (*ppdata == NULL) {
8623                 close_file(req, fsp, ERROR_CLOSE);
8624                 *pdata_return_size = 0;
8625                 return NT_STATUS_NO_MEMORY;
8626         }
8627         pdata = *ppdata;
8628
8629         if (extended_oplock_granted) {
8630                 if (flags & REQUEST_BATCH_OPLOCK) {
8631                         SSVAL(pdata,0, BATCH_OPLOCK_RETURN);
8632                 } else {
8633                         SSVAL(pdata,0, EXCLUSIVE_OPLOCK_RETURN);
8634                 }
8635         } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
8636                 SSVAL(pdata,0, LEVEL_II_OPLOCK_RETURN);
8637         } else {
8638                 SSVAL(pdata,0,NO_OPLOCK_RETURN);
8639         }
8640
8641         SSVAL(pdata,2,fsp->fnum);
8642         SIVAL(pdata,4,info); /* Was file created etc. */
8643
8644         switch (info_level_return) {
8645                 case SMB_QUERY_FILE_UNIX_BASIC:
8646                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
8647                         SSVAL(pdata,10,0); /* padding. */
8648                         store_file_unix_basic(conn, pdata + 12, fsp,
8649                                               &smb_fname->st);
8650                         break;
8651                 case SMB_QUERY_FILE_UNIX_INFO2:
8652                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
8653                         SSVAL(pdata,10,0); /* padding. */
8654                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
8655                                                     &smb_fname->st);
8656                         break;
8657                 default:
8658                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
8659                         SSVAL(pdata,10,0); /* padding. */
8660                         break;
8661         }
8662         return NT_STATUS_OK;
8663 }
8664
8665 /****************************************************************************
8666  Delete a file with POSIX semantics.
8667 ****************************************************************************/
8668
8669 static NTSTATUS smb_posix_unlink(connection_struct *conn,
8670                                  struct smb_request *req,
8671                                 const char *pdata,
8672                                 int total_data,
8673                                 struct smb_filename *smb_fname)
8674 {
8675         struct server_id self = messaging_server_id(conn->sconn->msg_ctx);
8676         NTSTATUS status = NT_STATUS_OK;
8677         files_struct *fsp = NULL;
8678         uint16_t flags = 0;
8679         char del = 1;
8680         int info = 0;
8681         int create_options = 0;
8682         struct share_mode_lock *lck = NULL;
8683         bool other_nonposix_opens;
8684
8685         if (total_data < 2) {
8686                 return NT_STATUS_INVALID_PARAMETER;
8687         }
8688
8689         flags = SVAL(pdata,0);
8690
8691         if (!VALID_STAT(smb_fname->st)) {
8692                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
8693         }
8694
8695         if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
8696                         !VALID_STAT_OF_DIR(smb_fname->st)) {
8697                 return NT_STATUS_NOT_A_DIRECTORY;
8698         }
8699
8700         DEBUG(10,("smb_posix_unlink: %s %s\n",
8701                 (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
8702                 smb_fname_str_dbg(smb_fname)));
8703
8704         if (VALID_STAT_OF_DIR(smb_fname->st)) {
8705                 create_options |= FILE_DIRECTORY_FILE;
8706         }
8707
8708         status = SMB_VFS_CREATE_FILE(
8709                 conn,                                   /* conn */
8710                 req,                                    /* req */
8711                 0,                                      /* root_dir_fid */
8712                 smb_fname,                              /* fname */
8713                 DELETE_ACCESS,                          /* access_mask */
8714                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
8715                     FILE_SHARE_DELETE),
8716                 FILE_OPEN,                              /* create_disposition*/
8717                 create_options,                         /* create_options */
8718                 FILE_FLAG_POSIX_SEMANTICS|0777,         /* file_attributes */
8719                 0,                                      /* oplock_request */
8720                 NULL,                                   /* lease */
8721                 0,                                      /* allocation_size */
8722                 0,                                      /* private_flags */
8723                 NULL,                                   /* sd */
8724                 NULL,                                   /* ea_list */
8725                 &fsp,                                   /* result */
8726                 &info,                                  /* pinfo */
8727                 NULL, NULL);                            /* create context */
8728
8729         if (!NT_STATUS_IS_OK(status)) {
8730                 return status;
8731         }
8732
8733         /*
8734          * Don't lie to client. If we can't really delete due to
8735          * non-POSIX opens return SHARING_VIOLATION.
8736          */
8737
8738         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
8739         if (lck == NULL) {
8740                 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
8741                           "lock for file %s\n", fsp_str_dbg(fsp)));
8742                 close_file(req, fsp, NORMAL_CLOSE);
8743                 return NT_STATUS_INVALID_PARAMETER;
8744         }
8745
8746         other_nonposix_opens = has_other_nonposix_opens(lck, fsp, self);
8747         if (other_nonposix_opens) {
8748                 /* Fail with sharing violation. */
8749                 TALLOC_FREE(lck);
8750                 close_file(req, fsp, NORMAL_CLOSE);
8751                 return NT_STATUS_SHARING_VIOLATION;
8752         }
8753
8754         /*
8755          * Set the delete on close.
8756          */
8757         status = smb_set_file_disposition_info(conn,
8758                                                 &del,
8759                                                 1,
8760                                                 fsp,
8761                                                 smb_fname);
8762
8763         TALLOC_FREE(lck);
8764
8765         if (!NT_STATUS_IS_OK(status)) {
8766                 close_file(req, fsp, NORMAL_CLOSE);
8767                 return status;
8768         }
8769         return close_file(req, fsp, NORMAL_CLOSE);
8770 }
8771
8772 NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
8773                                 struct smb_request *req,
8774                                 TALLOC_CTX *mem_ctx,
8775                                 uint16_t info_level,
8776                                 files_struct *fsp,
8777                                 struct smb_filename *smb_fname,
8778                                 char **ppdata, int total_data,
8779                                 int *ret_data_size)
8780 {
8781         char *pdata = *ppdata;
8782         NTSTATUS status = NT_STATUS_OK;
8783         int data_return_size = 0;
8784
8785         *ret_data_size = 0;
8786
8787         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
8788                 return NT_STATUS_INVALID_LEVEL;
8789         }
8790
8791         if (!CAN_WRITE(conn)) {
8792                 /* Allow POSIX opens. The open path will deny
8793                  * any non-readonly opens. */
8794                 if (info_level != SMB_POSIX_PATH_OPEN) {
8795                         return NT_STATUS_DOS(ERRSRV, ERRaccess);
8796                 }
8797         }
8798
8799         DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "
8800                  "totdata=%d\n", smb_fname_str_dbg(smb_fname),
8801                  fsp_fnum_dbg(fsp),
8802                  info_level, total_data));
8803
8804         switch (info_level) {
8805
8806                 case SMB_INFO_STANDARD:
8807                 {
8808                         status = smb_set_info_standard(conn,
8809                                         pdata,
8810                                         total_data,
8811                                         fsp,
8812                                         smb_fname);
8813                         break;
8814                 }
8815
8816                 case SMB_INFO_SET_EA:
8817                 {
8818                         status = smb_info_set_ea(conn,
8819                                                 pdata,
8820                                                 total_data,
8821                                                 fsp,
8822                                                 smb_fname);
8823                         break;
8824                 }
8825
8826                 case SMB_SET_FILE_BASIC_INFO:
8827                 case SMB_FILE_BASIC_INFORMATION:
8828                 {
8829                         status = smb_set_file_basic_info(conn,
8830                                                         pdata,
8831                                                         total_data,
8832                                                         fsp,
8833                                                         smb_fname);
8834                         break;
8835                 }
8836
8837                 case SMB_FILE_ALLOCATION_INFORMATION:
8838                 case SMB_SET_FILE_ALLOCATION_INFO:
8839                 {
8840                         status = smb_set_file_allocation_info(conn, req,
8841                                                                 pdata,
8842                                                                 total_data,
8843                                                                 fsp,
8844                                                                 smb_fname);
8845                         break;
8846                 }
8847
8848                 case SMB_FILE_END_OF_FILE_INFORMATION:
8849                 case SMB_SET_FILE_END_OF_FILE_INFO:
8850                 {
8851                         /*
8852                          * XP/Win7 both fail after the createfile with
8853                          * SMB_SET_FILE_END_OF_FILE_INFO but not
8854                          * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
8855                          * The level is known here, so pass it down
8856                          * appropriately.
8857                          */
8858                         bool should_fail =
8859                             (info_level == SMB_SET_FILE_END_OF_FILE_INFO);
8860
8861                         status = smb_set_file_end_of_file_info(conn, req,
8862                                                                 pdata,
8863                                                                 total_data,
8864                                                                 fsp,
8865                                                                 smb_fname,
8866                                                                 should_fail);
8867                         break;
8868                 }
8869
8870                 case SMB_FILE_DISPOSITION_INFORMATION:
8871                 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
8872                 {
8873 #if 0
8874                         /* JRA - We used to just ignore this on a path ? 
8875                          * Shouldn't this be invalid level on a pathname
8876                          * based call ?
8877                          */
8878                         if (tran_call != TRANSACT2_SETFILEINFO) {
8879                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
8880                         }
8881 #endif
8882                         status = smb_set_file_disposition_info(conn,
8883                                                 pdata,
8884                                                 total_data,
8885                                                 fsp,
8886                                                 smb_fname);
8887                         break;
8888                 }
8889
8890                 case SMB_FILE_POSITION_INFORMATION:
8891                 {
8892                         status = smb_file_position_information(conn,
8893                                                 pdata,
8894                                                 total_data,
8895                                                 fsp);
8896                         break;
8897                 }
8898
8899                 case SMB_FILE_FULL_EA_INFORMATION:
8900                 {
8901                         status = smb_set_file_full_ea_info(conn,
8902                                                 pdata,
8903                                                 total_data,
8904                                                 fsp);
8905                         break;
8906                 }
8907
8908                 /* From tridge Samba4 : 
8909                  * MODE_INFORMATION in setfileinfo (I have no
8910                  * idea what "mode information" on a file is - it takes a value of 0,
8911                  * 2, 4 or 6. What could it be?).
8912                  */
8913
8914                 case SMB_FILE_MODE_INFORMATION:
8915                 {
8916                         status = smb_file_mode_information(conn,
8917                                                 pdata,
8918                                                 total_data);
8919                         break;
8920                 }
8921
8922                 /* [MS-SMB2] 3.3.5.21.1 states we MUST fail with STATUS_NOT_SUPPORTED. */
8923                 case SMB_FILE_VALID_DATA_LENGTH_INFORMATION:
8924                 case SMB_FILE_SHORT_NAME_INFORMATION:
8925                         return NT_STATUS_NOT_SUPPORTED;
8926
8927                 /*
8928                  * CIFS UNIX extensions.
8929                  */
8930
8931                 case SMB_SET_FILE_UNIX_BASIC:
8932                 {
8933                         status = smb_set_file_unix_basic(conn, req,
8934                                                         pdata,
8935                                                         total_data,
8936                                                         fsp,
8937                                                         smb_fname);
8938                         break;
8939                 }
8940
8941                 case SMB_SET_FILE_UNIX_INFO2:
8942                 {
8943                         status = smb_set_file_unix_info2(conn, req,
8944                                                         pdata,
8945                                                         total_data,
8946                                                         fsp,
8947                                                         smb_fname);
8948                         break;
8949                 }
8950
8951                 case SMB_SET_FILE_UNIX_LINK:
8952                 {
8953                         if (fsp) {
8954                                 /* We must have a pathname for this. */
8955                                 return NT_STATUS_INVALID_LEVEL;
8956                         }
8957                         status = smb_set_file_unix_link(conn, req, pdata,
8958                                                         total_data, smb_fname);
8959                         break;
8960                 }
8961
8962                 case SMB_SET_FILE_UNIX_HLINK:
8963                 {
8964                         if (fsp) {
8965                                 /* We must have a pathname for this. */
8966                                 return NT_STATUS_INVALID_LEVEL;
8967                         }
8968                         status = smb_set_file_unix_hlink(conn, req,
8969                                                          pdata, total_data,
8970                                                          smb_fname);
8971                         break;
8972                 }
8973
8974                 case SMB_FILE_RENAME_INFORMATION:
8975                 {
8976                         status = smb_file_rename_information(conn, req,
8977                                                              pdata, total_data,
8978                                                              fsp, smb_fname);
8979                         break;
8980                 }
8981
8982                 case SMB2_FILE_RENAME_INFORMATION_INTERNAL:
8983                 {
8984                         /* SMB2 rename information. */
8985                         status = smb2_file_rename_information(conn, req,
8986                                                              pdata, total_data,
8987                                                              fsp, smb_fname);
8988                         break;
8989                 }
8990
8991                 case SMB_FILE_LINK_INFORMATION:
8992                 {
8993                         status = smb_file_link_information(conn, req,
8994                                                         pdata, total_data,
8995                                                         fsp, smb_fname);
8996                         break;
8997                 }
8998
8999 #if defined(HAVE_POSIX_ACLS)
9000                 case SMB_SET_POSIX_ACL:
9001                 {
9002                         status = smb_set_posix_acl(conn,
9003                                                 req,
9004                                                 pdata,
9005                                                 total_data,
9006                                                 fsp,
9007                                                 smb_fname);
9008                         break;
9009                 }
9010 #endif
9011
9012                 case SMB_SET_POSIX_LOCK:
9013                 {
9014                         if (!fsp) {
9015                                 return NT_STATUS_INVALID_LEVEL;
9016                         }
9017                         status = smb_set_posix_lock(conn, req,
9018                                                     pdata, total_data, fsp);
9019                         break;
9020                 }
9021
9022                 case SMB_POSIX_PATH_OPEN:
9023                 {
9024                         if (fsp) {
9025                                 /* We must have a pathname for this. */
9026                                 return NT_STATUS_INVALID_LEVEL;
9027                         }
9028
9029                         status = smb_posix_open(conn, req,
9030                                                 ppdata,
9031                                                 total_data,
9032                                                 smb_fname,
9033                                                 &data_return_size);
9034                         break;
9035                 }
9036
9037                 case SMB_POSIX_PATH_UNLINK:
9038                 {
9039                         if (fsp) {
9040                                 /* We must have a pathname for this. */
9041                                 return NT_STATUS_INVALID_LEVEL;
9042                         }
9043
9044                         status = smb_posix_unlink(conn, req,
9045                                                 pdata,
9046                                                 total_data,
9047                                                 smb_fname);
9048                         break;
9049                 }
9050
9051                 default:
9052                         return NT_STATUS_INVALID_LEVEL;
9053         }
9054
9055         if (!NT_STATUS_IS_OK(status)) {
9056                 return status;
9057         }
9058
9059         *ret_data_size = data_return_size;
9060         return NT_STATUS_OK;
9061 }
9062
9063 /****************************************************************************
9064  Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
9065 ****************************************************************************/
9066
9067 static void call_trans2setfilepathinfo(connection_struct *conn,
9068                                        struct smb_request *req,
9069                                        unsigned int tran_call,
9070                                        char **pparams, int total_params,
9071                                        char **ppdata, int total_data,
9072                                        unsigned int max_data_bytes)
9073 {
9074         char *params = *pparams;
9075         char *pdata = *ppdata;
9076         uint16_t info_level;
9077         struct smb_filename *smb_fname = NULL;
9078         files_struct *fsp = NULL;
9079         NTSTATUS status = NT_STATUS_OK;
9080         int data_return_size = 0;
9081
9082         if (!params) {
9083                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9084                 return;
9085         }
9086
9087         if (tran_call == TRANSACT2_SETFILEINFO) {
9088                 if (total_params < 4) {
9089                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9090                         return;
9091                 }
9092
9093                 fsp = file_fsp(req, SVAL(params,0));
9094                 /* Basic check for non-null fsp. */
9095                 if (!check_fsp_open(conn, req, fsp)) {
9096                         return;
9097                 }
9098                 info_level = SVAL(params,2);
9099
9100                 smb_fname = cp_smb_filename(talloc_tos(), fsp->fsp_name);
9101                 if (smb_fname == NULL) {
9102                         reply_nterror(req, NT_STATUS_NO_MEMORY);
9103                         return;
9104                 }
9105
9106                 if(fsp->fh->fd == -1) {
9107                         /*
9108                          * This is actually a SETFILEINFO on a directory
9109                          * handle (returned from an NT SMB). NT5.0 seems
9110                          * to do this call. JRA.
9111                          */
9112                         if (INFO_LEVEL_IS_UNIX(info_level)) {
9113                                 /* Always do lstat for UNIX calls. */
9114                                 if (SMB_VFS_LSTAT(conn, smb_fname)) {
9115                                         DEBUG(3,("call_trans2setfilepathinfo: "
9116                                                  "SMB_VFS_LSTAT of %s failed "
9117                                                  "(%s)\n",
9118                                                  smb_fname_str_dbg(smb_fname),
9119                                                  strerror(errno)));
9120                                         reply_nterror(req, map_nt_error_from_unix(errno));
9121                                         return;
9122                                 }
9123                         } else {
9124                                 if (SMB_VFS_STAT(conn, smb_fname) != 0) {
9125                                         DEBUG(3,("call_trans2setfilepathinfo: "
9126                                                  "fileinfo of %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                 } else if (fsp->print_file) {
9134                         /*
9135                          * Doing a DELETE_ON_CLOSE should cancel a print job.
9136                          */
9137                         if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
9138                                 fsp->fh->private_options |= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE;
9139
9140                                 DEBUG(3,("call_trans2setfilepathinfo: "
9141                                          "Cancelling print job (%s)\n",
9142                                          fsp_str_dbg(fsp)));
9143
9144                                 SSVAL(params,0,0);
9145                                 send_trans2_replies(conn, req, NT_STATUS_OK, params, 2,
9146                                                     *ppdata, 0,
9147                                                     max_data_bytes);
9148                                 return;
9149                         } else {
9150                                 reply_nterror(req,
9151                                         NT_STATUS_OBJECT_PATH_NOT_FOUND);
9152                                 return;
9153                         }
9154                 } else {
9155                         /*
9156                          * Original code - this is an open file.
9157                          */
9158                         if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
9159                                 DEBUG(3,("call_trans2setfilepathinfo: fstat "
9160                                          "of %s failed (%s)\n", fsp_fnum_dbg(fsp),
9161                                          strerror(errno)));
9162                                 reply_nterror(req, map_nt_error_from_unix(errno));
9163                                 return;
9164                         }
9165                 }
9166         } else {
9167                 char *fname = NULL;
9168                 uint32_t ucf_flags = ucf_flags_from_smb_request(req);
9169
9170                 /* set path info */
9171                 if (total_params < 7) {
9172                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9173                         return;
9174                 }
9175
9176                 info_level = SVAL(params,0);
9177                 if (req->posix_pathnames) {
9178                         srvstr_get_path_posix(req,
9179                                 params,
9180                                 req->flags2,
9181                                 &fname,
9182                                 &params[6],
9183                                 total_params - 6,
9184                                 STR_TERMINATE,
9185                                 &status);
9186                 } else {
9187                         srvstr_get_path(req,
9188                                 params,
9189                                 req->flags2,
9190                                 &fname,
9191                                 &params[6],
9192                                 total_params - 6,
9193                                 STR_TERMINATE,
9194                                 &status);
9195                 }
9196                 if (!NT_STATUS_IS_OK(status)) {
9197                         reply_nterror(req, status);
9198                         return;
9199                 }
9200
9201                 if (info_level == SMB_SET_FILE_UNIX_BASIC ||
9202                                 info_level == SMB_SET_FILE_UNIX_INFO2 ||
9203                                 info_level == SMB_FILE_RENAME_INFORMATION ||
9204                                 info_level == SMB_POSIX_PATH_OPEN ||
9205                                 info_level == SMB_POSIX_PATH_UNLINK) {
9206                         ucf_flags |= UCF_UNIX_NAME_LOOKUP;
9207                 }
9208
9209                 status = filename_convert(req, conn,
9210                                          fname,
9211                                          ucf_flags,
9212                                          NULL,
9213                                          NULL,
9214                                          &smb_fname);
9215                 if (!NT_STATUS_IS_OK(status)) {
9216                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
9217                                 reply_botherror(req,
9218                                                 NT_STATUS_PATH_NOT_COVERED,
9219                                                 ERRSRV, ERRbadpath);
9220                                 return;
9221                         }
9222                         reply_nterror(req, status);
9223                         return;
9224                 }
9225
9226                 if (INFO_LEVEL_IS_UNIX(info_level)) {
9227                         /*
9228                          * For CIFS UNIX extensions the target name may not exist.
9229                          */
9230
9231                         /* Always do lstat for UNIX calls. */
9232                         SMB_VFS_LSTAT(conn, smb_fname);
9233
9234                 } else if (!VALID_STAT(smb_fname->st) &&
9235                            SMB_VFS_STAT(conn, smb_fname)) {
9236                         DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
9237                                  "%s failed (%s)\n",
9238                                  smb_fname_str_dbg(smb_fname),
9239                                  strerror(errno)));
9240                         reply_nterror(req, map_nt_error_from_unix(errno));
9241                         return;
9242                 }
9243         }
9244
9245         DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
9246                  "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
9247                  fsp_fnum_dbg(fsp),
9248                  info_level,total_data));
9249
9250         /* Realloc the parameter size */
9251         *pparams = (char *)SMB_REALLOC(*pparams,2);
9252         if (*pparams == NULL) {
9253                 reply_nterror(req, NT_STATUS_NO_MEMORY);
9254                 return;
9255         }
9256         params = *pparams;
9257
9258         SSVAL(params,0,0);
9259
9260         status = smbd_do_setfilepathinfo(conn, req, req,
9261                                          info_level,
9262                                          fsp,
9263                                          smb_fname,
9264                                          ppdata, total_data,
9265                                          &data_return_size);
9266         if (!NT_STATUS_IS_OK(status)) {
9267                 if (open_was_deferred(req->xconn, req->mid)) {
9268                         /* We have re-scheduled this call. */
9269                         return;
9270                 }
9271                 if (NT_STATUS_EQUAL(status, NT_STATUS_EVENT_PENDING)) {
9272                         /* We have re-scheduled this call. */
9273                         return;
9274                 }
9275                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
9276                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
9277                                         ERRSRV, ERRbadpath);
9278                         return;
9279                 }
9280                 if (info_level == SMB_POSIX_PATH_OPEN) {
9281                         reply_openerror(req, status);
9282                         return;
9283                 }
9284
9285                 /*
9286                  * Invalid EA name needs to return 2 param bytes,
9287                  * not a zero-length error packet.
9288                  */
9289                 if (NT_STATUS_EQUAL(status, STATUS_INVALID_EA_NAME)) {
9290                         send_trans2_replies(conn, req, status, params, 2, NULL, 0,
9291                                         max_data_bytes);
9292                 } else {
9293                         reply_nterror(req, status);
9294                 }
9295                 return;
9296         }
9297
9298         send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, data_return_size,
9299                             max_data_bytes);
9300
9301         return;
9302 }
9303
9304 /****************************************************************************
9305  Reply to a TRANS2_MKDIR (make directory with extended attributes).
9306 ****************************************************************************/
9307
9308 static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
9309                              char **pparams, int total_params,
9310                              char **ppdata, int total_data,
9311                              unsigned int max_data_bytes)
9312 {
9313         struct smb_filename *smb_dname = NULL;
9314         char *params = *pparams;
9315         char *pdata = *ppdata;
9316         char *directory = NULL;
9317         NTSTATUS status = NT_STATUS_OK;
9318         struct ea_list *ea_list = NULL;
9319         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
9320         TALLOC_CTX *ctx = talloc_tos();
9321
9322         if (!CAN_WRITE(conn)) {
9323                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9324                 return;
9325         }
9326
9327         if (total_params < 5) {
9328                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9329                 return;
9330         }
9331
9332         if (req->posix_pathnames) {
9333                 srvstr_get_path_posix(ctx,
9334                         params,
9335                         req->flags2,
9336                         &directory,
9337                         &params[4],
9338                         total_params - 4,
9339                         STR_TERMINATE,
9340                         &status);
9341         } else {
9342                 srvstr_get_path(ctx,
9343                         params,
9344                         req->flags2,
9345                         &directory,
9346                         &params[4],
9347                         total_params - 4,
9348                         STR_TERMINATE,
9349                         &status);
9350         }
9351         if (!NT_STATUS_IS_OK(status)) {
9352                 reply_nterror(req, status);
9353                 return;
9354         }
9355
9356         DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
9357
9358         status = filename_convert(ctx,
9359                                 conn,
9360                                 directory,
9361                                 ucf_flags,
9362                                 NULL,
9363                                 NULL,
9364                                 &smb_dname);
9365
9366         if (!NT_STATUS_IS_OK(status)) {
9367                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
9368                         reply_botherror(req,
9369                                 NT_STATUS_PATH_NOT_COVERED,
9370                                 ERRSRV, ERRbadpath);
9371                         return;
9372                 }
9373                 reply_nterror(req, status);
9374                 return;
9375         }
9376
9377         /*
9378          * OS/2 workplace shell seems to send SET_EA requests of "null"
9379          * length (4 bytes containing IVAL 4).
9380          * They seem to have no effect. Bug #3212. JRA.
9381          */
9382
9383         if (total_data && (total_data != 4)) {
9384                 /* Any data in this call is an EA list. */
9385                 if (total_data < 10) {
9386                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9387                         goto out;
9388                 }
9389
9390                 if (IVAL(pdata,0) > total_data) {
9391                         DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
9392                                 IVAL(pdata,0), (unsigned int)total_data));
9393                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9394                         goto out;
9395                 }
9396
9397                 ea_list = read_ea_list(talloc_tos(), pdata + 4,
9398                                        total_data - 4);
9399                 if (!ea_list) {
9400                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9401                         goto out;
9402                 }
9403
9404                 if (!lp_ea_support(SNUM(conn))) {
9405                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
9406                         goto out;
9407                 }
9408         }
9409         /* If total_data == 4 Windows doesn't care what values
9410          * are placed in that field, it just ignores them.
9411          * The System i QNTC IBM SMB client puts bad values here,
9412          * so ignore them. */
9413
9414         status = create_directory(conn, req, smb_dname);
9415
9416         if (!NT_STATUS_IS_OK(status)) {
9417                 reply_nterror(req, status);
9418                 goto out;
9419         }
9420
9421         /* Try and set any given EA. */
9422         if (ea_list) {
9423                 status = set_ea(conn, NULL, smb_dname, ea_list);
9424                 if (!NT_STATUS_IS_OK(status)) {
9425                         reply_nterror(req, status);
9426                         goto out;
9427                 }
9428         }
9429
9430         /* Realloc the parameter and data sizes */
9431         *pparams = (char *)SMB_REALLOC(*pparams,2);
9432         if(*pparams == NULL) {
9433                 reply_nterror(req, NT_STATUS_NO_MEMORY);
9434                 goto out;
9435         }
9436         params = *pparams;
9437
9438         SSVAL(params,0,0);
9439
9440         send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, 0, max_data_bytes);
9441
9442  out:
9443         TALLOC_FREE(smb_dname);
9444         return;
9445 }
9446
9447 /****************************************************************************
9448  Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
9449  We don't actually do this - we just send a null response.
9450 ****************************************************************************/
9451
9452 static void call_trans2findnotifyfirst(connection_struct *conn,
9453                                        struct smb_request *req,
9454                                        char **pparams, int total_params,
9455                                        char **ppdata, int total_data,
9456                                        unsigned int max_data_bytes)
9457 {
9458         char *params = *pparams;
9459         uint16_t info_level;
9460
9461         if (total_params < 6) {
9462                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9463                 return;
9464         }
9465
9466         info_level = SVAL(params,4);
9467         DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
9468
9469         switch (info_level) {
9470                 case 1:
9471                 case 2:
9472                         break;
9473                 default:
9474                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
9475                         return;
9476         }
9477
9478         /* Realloc the parameter and data sizes */
9479         *pparams = (char *)SMB_REALLOC(*pparams,6);
9480         if (*pparams == NULL) {
9481                 reply_nterror(req, NT_STATUS_NO_MEMORY);
9482                 return;
9483         }
9484         params = *pparams;
9485
9486         SSVAL(params,0,fnf_handle);
9487         SSVAL(params,2,0); /* No changes */
9488         SSVAL(params,4,0); /* No EA errors */
9489
9490         fnf_handle++;
9491
9492         if(fnf_handle == 0)
9493                 fnf_handle = 257;
9494
9495         send_trans2_replies(conn, req, NT_STATUS_OK, params, 6, *ppdata, 0, max_data_bytes);
9496
9497         return;
9498 }
9499
9500 /****************************************************************************
9501  Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for 
9502  changes). Currently this does nothing.
9503 ****************************************************************************/
9504
9505 static void call_trans2findnotifynext(connection_struct *conn,
9506                                       struct smb_request *req,
9507                                       char **pparams, int total_params,
9508                                       char **ppdata, int total_data,
9509                                       unsigned int max_data_bytes)
9510 {
9511         char *params = *pparams;
9512
9513         DEBUG(3,("call_trans2findnotifynext\n"));
9514
9515         /* Realloc the parameter and data sizes */
9516         *pparams = (char *)SMB_REALLOC(*pparams,4);
9517         if (*pparams == NULL) {
9518                 reply_nterror(req, NT_STATUS_NO_MEMORY);
9519                 return;
9520         }
9521         params = *pparams;
9522
9523         SSVAL(params,0,0); /* No changes */
9524         SSVAL(params,2,0); /* No EA errors */
9525
9526         send_trans2_replies(conn, req, NT_STATUS_OK, params, 4, *ppdata, 0, max_data_bytes);
9527
9528         return;
9529 }
9530
9531 /****************************************************************************
9532  Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
9533 ****************************************************************************/
9534
9535 static void call_trans2getdfsreferral(connection_struct *conn,
9536                                       struct smb_request *req,
9537                                       char **pparams, int total_params,
9538                                       char **ppdata, int total_data,
9539                                       unsigned int max_data_bytes)
9540 {
9541         char *params = *pparams;
9542         char *pathname = NULL;
9543         int reply_size = 0;
9544         int max_referral_level;
9545         NTSTATUS status = NT_STATUS_OK;
9546         TALLOC_CTX *ctx = talloc_tos();
9547
9548         DEBUG(10,("call_trans2getdfsreferral\n"));
9549
9550         if (total_params < 3) {
9551                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9552                 return;
9553         }
9554
9555         max_referral_level = SVAL(params,0);
9556
9557         if(!lp_host_msdfs()) {
9558                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
9559                 return;
9560         }
9561
9562         srvstr_pull_talloc(ctx, params, req->flags2, &pathname, &params[2],
9563                     total_params - 2, STR_TERMINATE);
9564         if (!pathname) {
9565                 reply_nterror(req, NT_STATUS_NOT_FOUND);
9566                 return;
9567         }
9568         if((reply_size = setup_dfs_referral(conn, pathname, max_referral_level,
9569                                             ppdata,&status)) < 0) {
9570                 reply_nterror(req, status);
9571                 return;
9572         }
9573
9574         SSVAL((discard_const_p(uint8_t, req->inbuf)), smb_flg2,
9575               SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
9576         send_trans2_replies(conn, req, NT_STATUS_OK, 0,0,*ppdata,reply_size, max_data_bytes);
9577
9578         return;
9579 }
9580
9581 #define LMCAT_SPL       0x53
9582 #define LMFUNC_GETJOBID 0x60
9583
9584 /****************************************************************************
9585  Reply to a TRANS2_IOCTL - used for OS/2 printing.
9586 ****************************************************************************/
9587
9588 static void call_trans2ioctl(connection_struct *conn,
9589                              struct smb_request *req,
9590                              char **pparams, int total_params,
9591                              char **ppdata, int total_data,
9592                              unsigned int max_data_bytes)
9593 {
9594         char *pdata = *ppdata;
9595         files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0));
9596         NTSTATUS status;
9597         size_t len = 0;
9598
9599         /* check for an invalid fid before proceeding */
9600
9601         if (!fsp) {
9602                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
9603                 return;
9604         }
9605
9606         if ((SVAL(req->vwv+16, 0) == LMCAT_SPL)
9607             && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
9608                 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
9609                 if (*ppdata == NULL) {
9610                         reply_nterror(req, NT_STATUS_NO_MEMORY);
9611                         return;
9612                 }
9613                 pdata = *ppdata;
9614
9615                 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
9616                         CAN ACCEPT THIS IN UNICODE. JRA. */
9617
9618                 /* Job number */
9619                 SSVAL(pdata, 0, print_spool_rap_jobid(fsp->print_file));
9620
9621                 status = srvstr_push(pdata, req->flags2, pdata + 2,
9622                             lp_netbios_name(), 15,
9623                             STR_ASCII|STR_TERMINATE, &len); /* Our NetBIOS name */
9624                 if (!NT_STATUS_IS_OK(status)) {
9625                         reply_nterror(req, status);
9626                         return;
9627                 }
9628                 status = srvstr_push(pdata, req->flags2, pdata+18,
9629                             lp_servicename(talloc_tos(), SNUM(conn)), 13,
9630                             STR_ASCII|STR_TERMINATE, &len); /* Service name */
9631                 if (!NT_STATUS_IS_OK(status)) {
9632                         reply_nterror(req, status);
9633                         return;
9634                 }
9635                 send_trans2_replies(conn, req, NT_STATUS_OK, *pparams, 0, *ppdata, 32,
9636                                     max_data_bytes);
9637                 return;
9638         }
9639
9640         DEBUG(2,("Unknown TRANS2_IOCTL\n"));
9641         reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
9642 }
9643
9644 /****************************************************************************
9645  Reply to a SMBfindclose (stop trans2 directory search).
9646 ****************************************************************************/
9647
9648 void reply_findclose(struct smb_request *req)
9649 {
9650         int dptr_num;
9651         struct smbd_server_connection *sconn = req->sconn;
9652
9653         START_PROFILE(SMBfindclose);
9654
9655         if (req->wct < 1) {
9656                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9657                 END_PROFILE(SMBfindclose);
9658                 return;
9659         }
9660
9661         dptr_num = SVALS(req->vwv+0, 0);
9662
9663         DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
9664
9665         dptr_close(sconn, &dptr_num);
9666
9667         reply_outbuf(req, 0, 0);
9668
9669         DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
9670
9671         END_PROFILE(SMBfindclose);
9672         return;
9673 }
9674
9675 /****************************************************************************
9676  Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
9677 ****************************************************************************/
9678
9679 void reply_findnclose(struct smb_request *req)
9680 {
9681         int dptr_num;
9682
9683         START_PROFILE(SMBfindnclose);
9684
9685         if (req->wct < 1) {
9686                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9687                 END_PROFILE(SMBfindnclose);
9688                 return;
9689         }
9690
9691         dptr_num = SVAL(req->vwv+0, 0);
9692
9693         DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
9694
9695         /* We never give out valid handles for a 
9696            findnotifyfirst - so any dptr_num is ok here. 
9697            Just ignore it. */
9698
9699         reply_outbuf(req, 0, 0);
9700
9701         DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
9702
9703         END_PROFILE(SMBfindnclose);
9704         return;
9705 }
9706
9707 static void handle_trans2(connection_struct *conn, struct smb_request *req,
9708                           struct trans_state *state)
9709 {
9710         if (get_Protocol() >= PROTOCOL_NT1) {
9711                 req->flags2 |= 0x40; /* IS_LONG_NAME */
9712                 SSVAL((discard_const_p(uint8_t, req->inbuf)),smb_flg2,req->flags2);
9713         }
9714
9715         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
9716                 if (state->call != TRANSACT2_QFSINFO &&
9717                     state->call != TRANSACT2_SETFSINFO) {
9718                         DEBUG(0,("handle_trans2: encryption required "
9719                                 "with call 0x%x\n",
9720                                 (unsigned int)state->call));
9721                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9722                         return;
9723                 }
9724         }
9725
9726         SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
9727
9728         /* Now we must call the relevant TRANS2 function */
9729         switch(state->call)  {
9730         case TRANSACT2_OPEN:
9731         {
9732                 START_PROFILE(Trans2_open);
9733                 call_trans2open(conn, req,
9734                                 &state->param, state->total_param,
9735                                 &state->data, state->total_data,
9736                                 state->max_data_return);
9737                 END_PROFILE(Trans2_open);
9738                 break;
9739         }
9740
9741         case TRANSACT2_FINDFIRST:
9742         {
9743                 START_PROFILE(Trans2_findfirst);
9744                 call_trans2findfirst(conn, req,
9745                                      &state->param, state->total_param,
9746                                      &state->data, state->total_data,
9747                                      state->max_data_return);
9748                 END_PROFILE(Trans2_findfirst);
9749                 break;
9750         }
9751
9752         case TRANSACT2_FINDNEXT:
9753         {
9754                 START_PROFILE(Trans2_findnext);
9755                 call_trans2findnext(conn, req,
9756                                     &state->param, state->total_param,
9757                                     &state->data, state->total_data,
9758                                     state->max_data_return);
9759                 END_PROFILE(Trans2_findnext);
9760                 break;
9761         }
9762
9763         case TRANSACT2_QFSINFO:
9764         {
9765                 START_PROFILE(Trans2_qfsinfo);
9766                 call_trans2qfsinfo(conn, req,
9767                                    &state->param, state->total_param,
9768                                    &state->data, state->total_data,
9769                                    state->max_data_return);
9770                 END_PROFILE(Trans2_qfsinfo);
9771             break;
9772         }
9773
9774         case TRANSACT2_SETFSINFO:
9775         {
9776                 START_PROFILE(Trans2_setfsinfo);
9777                 call_trans2setfsinfo(conn, req,
9778                                      &state->param, state->total_param,
9779                                      &state->data, state->total_data,
9780                                      state->max_data_return);
9781                 END_PROFILE(Trans2_setfsinfo);
9782                 break;
9783         }
9784
9785         case TRANSACT2_QPATHINFO:
9786         case TRANSACT2_QFILEINFO:
9787         {
9788                 START_PROFILE(Trans2_qpathinfo);
9789                 call_trans2qfilepathinfo(conn, req, state->call,
9790                                          &state->param, state->total_param,
9791                                          &state->data, state->total_data,
9792                                          state->max_data_return);
9793                 END_PROFILE(Trans2_qpathinfo);
9794                 break;
9795         }
9796
9797         case TRANSACT2_SETPATHINFO:
9798         case TRANSACT2_SETFILEINFO:
9799         {
9800                 START_PROFILE(Trans2_setpathinfo);
9801                 call_trans2setfilepathinfo(conn, req, state->call,
9802                                            &state->param, state->total_param,
9803                                            &state->data, state->total_data,
9804                                            state->max_data_return);
9805                 END_PROFILE(Trans2_setpathinfo);
9806                 break;
9807         }
9808
9809         case TRANSACT2_FINDNOTIFYFIRST:
9810         {
9811                 START_PROFILE(Trans2_findnotifyfirst);
9812                 call_trans2findnotifyfirst(conn, req,
9813                                            &state->param, state->total_param,
9814                                            &state->data, state->total_data,
9815                                            state->max_data_return);
9816                 END_PROFILE(Trans2_findnotifyfirst);
9817                 break;
9818         }
9819
9820         case TRANSACT2_FINDNOTIFYNEXT:
9821         {
9822                 START_PROFILE(Trans2_findnotifynext);
9823                 call_trans2findnotifynext(conn, req,
9824                                           &state->param, state->total_param,
9825                                           &state->data, state->total_data,
9826                                           state->max_data_return);
9827                 END_PROFILE(Trans2_findnotifynext);
9828                 break;
9829         }
9830
9831         case TRANSACT2_MKDIR:
9832         {
9833                 START_PROFILE(Trans2_mkdir);
9834                 call_trans2mkdir(conn, req,
9835                                  &state->param, state->total_param,
9836                                  &state->data, state->total_data,
9837                                  state->max_data_return);
9838                 END_PROFILE(Trans2_mkdir);
9839                 break;
9840         }
9841
9842         case TRANSACT2_GET_DFS_REFERRAL:
9843         {
9844                 START_PROFILE(Trans2_get_dfs_referral);
9845                 call_trans2getdfsreferral(conn, req,
9846                                           &state->param, state->total_param,
9847                                           &state->data, state->total_data,
9848                                           state->max_data_return);
9849                 END_PROFILE(Trans2_get_dfs_referral);
9850                 break;
9851         }
9852
9853         case TRANSACT2_IOCTL:
9854         {
9855                 START_PROFILE(Trans2_ioctl);
9856                 call_trans2ioctl(conn, req,
9857                                  &state->param, state->total_param,
9858                                  &state->data, state->total_data,
9859                                  state->max_data_return);
9860                 END_PROFILE(Trans2_ioctl);
9861                 break;
9862         }
9863
9864         default:
9865                 /* Error in request */
9866                 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
9867                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
9868         }
9869 }
9870
9871 /****************************************************************************
9872  Reply to a SMBtrans2.
9873  ****************************************************************************/
9874
9875 void reply_trans2(struct smb_request *req)
9876 {
9877         connection_struct *conn = req->conn;
9878         unsigned int dsoff;
9879         unsigned int dscnt;
9880         unsigned int psoff;
9881         unsigned int pscnt;
9882         unsigned int tran_call;
9883         struct trans_state *state;
9884         NTSTATUS result;
9885
9886         START_PROFILE(SMBtrans2);
9887
9888         if (req->wct < 14) {
9889                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9890                 END_PROFILE(SMBtrans2);
9891                 return;
9892         }
9893
9894         dsoff = SVAL(req->vwv+12, 0);
9895         dscnt = SVAL(req->vwv+11, 0);
9896         psoff = SVAL(req->vwv+10, 0);
9897         pscnt = SVAL(req->vwv+9, 0);
9898         tran_call = SVAL(req->vwv+14, 0);
9899
9900         result = allow_new_trans(conn->pending_trans, req->mid);
9901         if (!NT_STATUS_IS_OK(result)) {
9902                 DEBUG(2, ("Got invalid trans2 request: %s\n",
9903                           nt_errstr(result)));
9904                 reply_nterror(req, result);
9905                 END_PROFILE(SMBtrans2);
9906                 return;
9907         }
9908
9909         if (IS_IPC(conn)) {
9910                 switch (tran_call) {
9911                 /* List the allowed trans2 calls on IPC$ */
9912                 case TRANSACT2_OPEN:
9913                 case TRANSACT2_GET_DFS_REFERRAL:
9914                 case TRANSACT2_QFILEINFO:
9915                 case TRANSACT2_QFSINFO:
9916                 case TRANSACT2_SETFSINFO:
9917                         break;
9918                 default:
9919                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9920                         END_PROFILE(SMBtrans2);
9921                         return;
9922                 }
9923         }
9924
9925         if ((state = talloc(conn, struct trans_state)) == NULL) {
9926                 DEBUG(0, ("talloc failed\n"));
9927                 reply_nterror(req, NT_STATUS_NO_MEMORY);
9928                 END_PROFILE(SMBtrans2);
9929                 return;
9930         }
9931
9932         state->cmd = SMBtrans2;
9933
9934         state->mid = req->mid;
9935         state->vuid = req->vuid;
9936         state->setup_count = SVAL(req->vwv+13, 0);
9937         state->setup = NULL;
9938         state->total_param = SVAL(req->vwv+0, 0);
9939         state->param = NULL;
9940         state->total_data =  SVAL(req->vwv+1, 0);
9941         state->data = NULL;
9942         state->max_param_return = SVAL(req->vwv+2, 0);
9943         state->max_data_return  = SVAL(req->vwv+3, 0);
9944         state->max_setup_return = SVAL(req->vwv+4, 0);
9945         state->close_on_completion = BITSETW(req->vwv+5, 0);
9946         state->one_way = BITSETW(req->vwv+5, 1);
9947
9948         state->call = tran_call;
9949
9950         /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
9951            is so as a sanity check */
9952         if (state->setup_count != 1) {
9953                 /*
9954                  * Need to have rc=0 for ioctl to get job id for OS/2.
9955                  *  Network printing will fail if function is not successful.
9956                  *  Similar function in reply.c will be used if protocol
9957                  *  is LANMAN1.0 instead of LM1.2X002.
9958                  *  Until DosPrintSetJobInfo with PRJINFO3 is supported,
9959                  *  outbuf doesn't have to be set(only job id is used).
9960                  */
9961                 if ( (state->setup_count == 4)
9962                      && (tran_call == TRANSACT2_IOCTL)
9963                      && (SVAL(req->vwv+16, 0) == LMCAT_SPL)
9964                      && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
9965                         DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
9966                 } else {
9967                         DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
9968                         DEBUG(2,("Transaction is %d\n",tran_call));
9969                         TALLOC_FREE(state);
9970                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9971                         END_PROFILE(SMBtrans2);
9972                         return;
9973                 }
9974         }
9975
9976         if ((dscnt > state->total_data) || (pscnt > state->total_param))
9977                 goto bad_param;
9978
9979         if (state->total_data) {
9980
9981                 if (trans_oob(state->total_data, 0, dscnt)
9982                     || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
9983                         goto bad_param;
9984                 }
9985
9986                 /* Can't use talloc here, the core routines do realloc on the
9987                  * params and data. */
9988                 state->data = (char *)SMB_MALLOC(state->total_data);
9989                 if (state->data == NULL) {
9990                         DEBUG(0,("reply_trans2: data malloc fail for %u "
9991                                  "bytes !\n", (unsigned int)state->total_data));
9992                         TALLOC_FREE(state);
9993                         reply_nterror(req, NT_STATUS_NO_MEMORY);
9994                         END_PROFILE(SMBtrans2);
9995                         return;
9996                 }
9997
9998                 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
9999         }
10000
10001         if (state->total_param) {
10002
10003                 if (trans_oob(state->total_param, 0, pscnt)
10004                     || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
10005                         goto bad_param;
10006                 }
10007
10008                 /* Can't use talloc here, the core routines do realloc on the
10009                  * params and data. */
10010                 state->param = (char *)SMB_MALLOC(state->total_param);
10011                 if (state->param == NULL) {
10012                         DEBUG(0,("reply_trans: param malloc fail for %u "
10013                                  "bytes !\n", (unsigned int)state->total_param));
10014                         SAFE_FREE(state->data);
10015                         TALLOC_FREE(state);
10016                         reply_nterror(req, NT_STATUS_NO_MEMORY);
10017                         END_PROFILE(SMBtrans2);
10018                         return;
10019                 } 
10020
10021                 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
10022         }
10023
10024         state->received_data  = dscnt;
10025         state->received_param = pscnt;
10026
10027         if ((state->received_param == state->total_param) &&
10028             (state->received_data == state->total_data)) {
10029
10030                 handle_trans2(conn, req, state);
10031
10032                 SAFE_FREE(state->data);
10033                 SAFE_FREE(state->param);
10034                 TALLOC_FREE(state);
10035                 END_PROFILE(SMBtrans2);
10036                 return;
10037         }
10038
10039         DLIST_ADD(conn->pending_trans, state);
10040
10041         /* We need to send an interim response then receive the rest
10042            of the parameter/data bytes */
10043         reply_outbuf(req, 0, 0);
10044         show_msg((char *)req->outbuf);
10045         END_PROFILE(SMBtrans2);
10046         return;
10047
10048   bad_param:
10049
10050         DEBUG(0,("reply_trans2: invalid trans parameters\n"));
10051         SAFE_FREE(state->data);
10052         SAFE_FREE(state->param);
10053         TALLOC_FREE(state);
10054         END_PROFILE(SMBtrans2);
10055         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10056 }
10057
10058
10059 /****************************************************************************
10060  Reply to a SMBtranss2
10061  ****************************************************************************/
10062
10063 void reply_transs2(struct smb_request *req)
10064 {
10065         connection_struct *conn = req->conn;
10066         unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
10067         struct trans_state *state;
10068
10069         START_PROFILE(SMBtranss2);
10070
10071         show_msg((const char *)req->inbuf);
10072
10073         /* Windows clients expect all replies to
10074            a transact secondary (SMBtranss2 0x33)
10075            to have a command code of transact
10076            (SMBtrans2 0x32). See bug #8989
10077            and also [MS-CIFS] section 2.2.4.47.2
10078            for details.
10079         */
10080         req->cmd = SMBtrans2;
10081
10082         if (req->wct < 8) {
10083                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10084                 END_PROFILE(SMBtranss2);
10085                 return;
10086         }
10087
10088         for (state = conn->pending_trans; state != NULL;
10089              state = state->next) {
10090                 if (state->mid == req->mid) {
10091                         break;
10092                 }
10093         }
10094
10095         if ((state == NULL) || (state->cmd != SMBtrans2)) {
10096                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10097                 END_PROFILE(SMBtranss2);
10098                 return;
10099         }
10100
10101         /* Revise state->total_param and state->total_data in case they have
10102            changed downwards */
10103
10104         if (SVAL(req->vwv+0, 0) < state->total_param)
10105                 state->total_param = SVAL(req->vwv+0, 0);
10106         if (SVAL(req->vwv+1, 0) < state->total_data)
10107                 state->total_data = SVAL(req->vwv+1, 0);
10108
10109         pcnt = SVAL(req->vwv+2, 0);
10110         poff = SVAL(req->vwv+3, 0);
10111         pdisp = SVAL(req->vwv+4, 0);
10112
10113         dcnt = SVAL(req->vwv+5, 0);
10114         doff = SVAL(req->vwv+6, 0);
10115         ddisp = SVAL(req->vwv+7, 0);
10116
10117         state->received_param += pcnt;
10118         state->received_data += dcnt;
10119
10120         if ((state->received_data > state->total_data) ||
10121             (state->received_param > state->total_param))
10122                 goto bad_param;
10123
10124         if (pcnt) {
10125                 if (trans_oob(state->total_param, pdisp, pcnt)
10126                     || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
10127                         goto bad_param;
10128                 }
10129                 memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
10130         }
10131
10132         if (dcnt) {
10133                 if (trans_oob(state->total_data, ddisp, dcnt)
10134                     || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
10135                         goto bad_param;
10136                 }
10137                 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
10138         }
10139
10140         if ((state->received_param < state->total_param) ||
10141             (state->received_data < state->total_data)) {
10142                 END_PROFILE(SMBtranss2);
10143                 return;
10144         }
10145
10146         handle_trans2(conn, req, state);
10147
10148         DLIST_REMOVE(conn->pending_trans, state);
10149         SAFE_FREE(state->data);
10150         SAFE_FREE(state->param);
10151         TALLOC_FREE(state);
10152
10153         END_PROFILE(SMBtranss2);
10154         return;
10155
10156   bad_param:
10157
10158         DEBUG(0,("reply_transs2: invalid trans parameters\n"));
10159         DLIST_REMOVE(conn->pending_trans, state);
10160         SAFE_FREE(state->data);
10161         SAFE_FREE(state->param);
10162         TALLOC_FREE(state);
10163         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10164         END_PROFILE(SMBtranss2);
10165         return;
10166 }