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