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