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