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