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