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