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