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