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