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