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