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