smbd: return correct error when trying to create a hardlink to a VSS file
[samba.git] / source3 / smbd / smb2_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 "../librpc/gen_ndr/ndr_smb3posix.h"
37 #include "libcli/security/security.h"
38 #include "trans2.h"
39 #include "auth.h"
40 #include "smbprofile.h"
41 #include "rpc_server/srv_pipe_hnd.h"
42 #include "printing.h"
43 #include "lib/util_ea.h"
44 #include "lib/readdir_attr.h"
45 #include "messages.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 #include "source3/smbd/dir.h"
51
52 #define DIR_ENTRY_SAFETY_MARGIN 4096
53
54 static uint32_t generate_volume_serial_number(
55                                 const struct loadparm_substitution *lp_sub,
56                                 int snum);
57
58 /****************************************************************************
59  Check if an open file handle is a symlink.
60 ****************************************************************************/
61
62 NTSTATUS refuse_symlink_fsp(const files_struct *fsp)
63 {
64
65         if (!VALID_STAT(fsp->fsp_name->st)) {
66                 return NT_STATUS_ACCESS_DENIED;
67         }
68         if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
69                 return NT_STATUS_ACCESS_DENIED;
70         }
71         if (fsp_get_pathref_fd(fsp) == -1) {
72                 return NT_STATUS_ACCESS_DENIED;
73         }
74         return NT_STATUS_OK;
75 }
76
77 /**
78  * Check that one or more of the rights in access mask are
79  * allowed. Iow, access_requested can contain more then one right and
80  * it is sufficient having only one of those granted to pass.
81  **/
82 NTSTATUS check_any_access_fsp(struct files_struct *fsp,
83                               uint32_t access_requested)
84 {
85         uint32_t access_granted = 0;
86         NTSTATUS status;
87
88         if (fsp->fsp_flags.is_fsa) {
89                 access_granted = fsp->access_mask;
90         } else {
91                 uint32_t mask = 1;
92
93                 while (mask != 0) {
94                         if (!(mask & access_requested)) {
95                                 mask <<= 1;
96                                 continue;
97                         }
98
99                         status = smbd_check_access_rights_fsp(
100                                                         fsp->conn->cwd_fsp,
101                                                         fsp,
102                                                         false,
103                                                         mask);
104                         if (NT_STATUS_IS_OK(status)) {
105                                 break;
106                         }
107                         mask <<= 1;
108                 }
109                 access_granted = mask;
110         }
111         if ((access_granted & access_requested) == 0) {
112                 return NT_STATUS_ACCESS_DENIED;
113         }
114         return NT_STATUS_OK;
115 }
116
117 /********************************************************************
118  Roundup a value to the nearest allocation roundup size boundary.
119  Only do this for Windows clients.
120 ********************************************************************/
121
122 uint64_t smb_roundup(connection_struct *conn, uint64_t val)
123 {
124         uint64_t rval = lp_allocation_roundup_size(SNUM(conn));
125
126         /* Only roundup for Windows clients. */
127         enum remote_arch_types ra_type = get_remote_arch();
128         if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
129                 val = SMB_ROUNDUP(val,rval);
130         }
131         return val;
132 }
133
134 /****************************************************************************
135  Utility functions for dealing with extended attributes.
136 ****************************************************************************/
137
138 /****************************************************************************
139  Refuse to allow clients to overwrite our private xattrs.
140 ****************************************************************************/
141
142 bool samba_private_attr_name(const char *unix_ea_name)
143 {
144         bool prohibited = false;
145
146         prohibited |= strequal(unix_ea_name, SAMBA_POSIX_INHERITANCE_EA_NAME);
147         prohibited |= strequal(unix_ea_name, SAMBA_XATTR_DOS_ATTRIB);
148         prohibited |= strequal(unix_ea_name, SAMBA_XATTR_MARKER);
149         prohibited |= strequal(unix_ea_name, XATTR_NTACL_NAME);
150         prohibited |= strequal(unix_ea_name, AFPINFO_EA_NETATALK);
151
152         if (prohibited) {
153                 return true;
154         }
155
156         if (strncasecmp_m(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
157                         strlen(SAMBA_XATTR_DOSSTREAM_PREFIX)) == 0) {
158                 return true;
159         }
160         return false;
161 }
162
163 /****************************************************************************
164  Get one EA value. Fill in a struct ea_struct.
165 ****************************************************************************/
166
167 NTSTATUS get_ea_value_fsp(TALLOC_CTX *mem_ctx,
168                           files_struct *fsp,
169                           const char *ea_name,
170                           struct ea_struct *pea)
171 {
172         /* Get the value of this xattr. Max size is 64k. */
173         size_t attr_size = 256;
174         char *val = NULL;
175         ssize_t sizeret;
176         size_t max_xattr_size = 0;
177         NTSTATUS status;
178
179         if (fsp == NULL) {
180                 return NT_STATUS_INVALID_HANDLE;
181         }
182         status = refuse_symlink_fsp(fsp);
183         if (!NT_STATUS_IS_OK(status)) {
184                 return status;
185         }
186
187         max_xattr_size = lp_smbd_max_xattr_size(SNUM(fsp->conn));
188
189  again:
190
191         val = talloc_realloc(mem_ctx, val, char, attr_size);
192         if (!val) {
193                 return NT_STATUS_NO_MEMORY;
194         }
195
196         sizeret = SMB_VFS_FGETXATTR(fsp, ea_name, val, attr_size);
197         if (sizeret == -1 && errno == ERANGE && attr_size < max_xattr_size) {
198                 attr_size = max_xattr_size;
199                 goto again;
200         }
201
202         if (sizeret == -1) {
203                 return map_nt_error_from_unix(errno);
204         }
205
206         DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name, (unsigned int)sizeret));
207         dump_data(10, (uint8_t *)val, sizeret);
208
209         pea->flags = 0;
210         if (strnequal(ea_name, "user.", 5)) {
211                 pea->name = talloc_strdup(mem_ctx, &ea_name[5]);
212         } else {
213                 pea->name = talloc_strdup(mem_ctx, ea_name);
214         }
215         if (pea->name == NULL) {
216                 TALLOC_FREE(val);
217                 return NT_STATUS_NO_MEMORY;
218         }
219         pea->value.data = (unsigned char *)val;
220         pea->value.length = (size_t)sizeret;
221         return NT_STATUS_OK;
222 }
223
224 NTSTATUS get_ea_names_from_fsp(TALLOC_CTX *mem_ctx,
225                                 files_struct *fsp,
226                                 char ***pnames,
227                                 size_t *pnum_names)
228 {
229         char smallbuf[1024];
230         /* Get a list of all xattrs. Max namesize is 64k. */
231         size_t ea_namelist_size = 1024;
232         char *ea_namelist = smallbuf;
233         char *to_free = NULL;
234
235         char *p;
236         char **names;
237         size_t num_names;
238         ssize_t sizeret = -1;
239         NTSTATUS status;
240
241         if (pnames) {
242                 *pnames = NULL;
243         }
244         *pnum_names = 0;
245
246         if ((fsp == NULL) || !NT_STATUS_IS_OK(refuse_symlink_fsp(fsp))) {
247                 /*
248                  * Callers may pass fsp == NULL when passing smb_fname->fsp of a
249                  * symlink. This is ok, handle it here, by just return no EA's
250                  * on a symlink.
251                  */
252                 return NT_STATUS_OK;
253         }
254
255         sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
256                                      ea_namelist_size);
257
258         if ((sizeret == -1) && (errno == ERANGE)) {
259                 ea_namelist_size = 65536;
260                 ea_namelist = talloc_array(mem_ctx, char, ea_namelist_size);
261                 if (ea_namelist == NULL) {
262                         return NT_STATUS_NO_MEMORY;
263                 }
264                 to_free = ea_namelist;
265
266                 sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
267                                              ea_namelist_size);
268         }
269
270         if (sizeret == -1) {
271                 status = map_nt_error_from_unix(errno);
272                 TALLOC_FREE(to_free);
273                 return status;
274         }
275
276         DBG_DEBUG("ea_namelist size = %zd\n", sizeret);
277
278         if (sizeret == 0) {
279                 TALLOC_FREE(to_free);
280                 return NT_STATUS_OK;
281         }
282
283         /*
284          * Ensure the result is 0-terminated
285          */
286
287         if (ea_namelist[sizeret-1] != '\0') {
288                 TALLOC_FREE(to_free);
289                 return NT_STATUS_INTERNAL_ERROR;
290         }
291
292         /*
293          * count the names
294          */
295         num_names = 0;
296
297         for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
298                 num_names += 1;
299         }
300
301         *pnum_names = num_names;
302
303         if (pnames == NULL) {
304                 TALLOC_FREE(to_free);
305                 return NT_STATUS_OK;
306         }
307
308         names = talloc_array(mem_ctx, char *, num_names);
309         if (names == NULL) {
310                 DEBUG(0, ("talloc failed\n"));
311                 TALLOC_FREE(to_free);
312                 return NT_STATUS_NO_MEMORY;
313         }
314
315         if (ea_namelist == smallbuf) {
316                 ea_namelist = talloc_memdup(names, smallbuf, sizeret);
317                 if (ea_namelist == NULL) {
318                         TALLOC_FREE(names);
319                         return NT_STATUS_NO_MEMORY;
320                 }
321         } else {
322                 talloc_steal(names, ea_namelist);
323
324                 ea_namelist = talloc_realloc(names, ea_namelist, char,
325                                              sizeret);
326                 if (ea_namelist == NULL) {
327                         TALLOC_FREE(names);
328                         return NT_STATUS_NO_MEMORY;
329                 }
330         }
331
332         num_names = 0;
333
334         for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
335                 names[num_names++] = p;
336         }
337
338         *pnames = names;
339
340         return NT_STATUS_OK;
341 }
342
343 /****************************************************************************
344  Return a linked list of the total EA's. Plus the total size
345 ****************************************************************************/
346
347 static NTSTATUS get_ea_list_from_fsp(TALLOC_CTX *mem_ctx,
348                                 files_struct *fsp,
349                                 size_t *pea_total_len,
350                                 struct ea_list **ea_list)
351 {
352         /* Get a list of all xattrs. Max namesize is 64k. */
353         size_t i, num_names;
354         char **names;
355         struct ea_list *ea_list_head = NULL;
356         bool posix_pathnames = false;
357         NTSTATUS status;
358
359         *pea_total_len = 0;
360         *ea_list = NULL;
361
362         /* symlink */
363         if (fsp == NULL) {
364                 return NT_STATUS_OK;
365         }
366
367         if (!lp_ea_support(SNUM(fsp->conn))) {
368                 return NT_STATUS_OK;
369         }
370
371         if (fsp_is_alternate_stream(fsp)) {
372                 return NT_STATUS_INVALID_PARAMETER;
373         }
374
375         posix_pathnames = (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
376
377         status = get_ea_names_from_fsp(talloc_tos(),
378                                 fsp,
379                                 &names,
380                                 &num_names);
381
382         if (!NT_STATUS_IS_OK(status)) {
383                 return status;
384         }
385
386         if (num_names == 0) {
387                 return NT_STATUS_OK;
388         }
389
390         for (i=0; i<num_names; i++) {
391                 struct ea_list *listp;
392                 fstring dos_ea_name;
393
394                 /*
395                  * POSIX EA names are divided into several namespaces by
396                  * means of string prefixes. Usually, the system controls
397                  * semantics for each namespace, but the 'user' namespace is
398                  * available for arbitrary use, which comes closest to
399                  * Windows EA semantics. Hence, we map POSIX EAs from the
400                  * 'user' namespace to Windows EAs, and just ignore all the
401                  * other namespaces. Also, a few specific names in the 'user'
402                  * namespace are used by Samba internally. Filter them out as
403                  * well, and only present the EAs that are available for
404                  * arbitrary use.
405                  */
406                 if (!strnequal(names[i], "user.", 5)
407                     || samba_private_attr_name(names[i]))
408                         continue;
409
410                 /*
411                  * Filter out any underlying POSIX EA names
412                  * that a Windows client can't handle.
413                  */
414                 if (!posix_pathnames &&
415                                 is_invalid_windows_ea_name(names[i])) {
416                         continue;
417                 }
418
419                 listp = talloc(mem_ctx, struct ea_list);
420                 if (listp == NULL) {
421                         return NT_STATUS_NO_MEMORY;
422                 }
423
424                 status = get_ea_value_fsp(listp,
425                                           fsp,
426                                           names[i],
427                                           &listp->ea);
428
429                 if (!NT_STATUS_IS_OK(status)) {
430                         TALLOC_FREE(listp);
431                         return status;
432                 }
433
434                 if (listp->ea.value.length == 0) {
435                         /*
436                          * We can never return a zero length EA.
437                          * Windows reports the EA's as corrupted.
438                          */
439                         TALLOC_FREE(listp);
440                         continue;
441                 } else if (listp->ea.value.length > 65536) {
442                         /*
443                          * SMB clients may report error with file
444                          * if large EA is presented to them.
445                          */
446                         DBG_ERR("EA [%s] on file [%s] exceeds "
447                                 "maximum permitted EA size of 64KiB: %zu\n.",
448                                 listp->ea.name, fsp_str_dbg(fsp),
449                                 listp->ea.value.length);
450                         TALLOC_FREE(listp);
451                         continue;
452                 }
453
454                 push_ascii_fstring(dos_ea_name, listp->ea.name);
455
456                 *pea_total_len +=
457                         4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
458
459                 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
460                           "= %u\n", (unsigned int)*pea_total_len, dos_ea_name,
461                           (unsigned int)listp->ea.value.length));
462
463                 DLIST_ADD_END(ea_list_head, listp);
464
465         }
466
467         /* Add on 4 for total length. */
468         if (*pea_total_len) {
469                 *pea_total_len += 4;
470         }
471
472         DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
473                    (unsigned int)*pea_total_len));
474
475         *ea_list = ea_list_head;
476         return NT_STATUS_OK;
477 }
478
479 /****************************************************************************
480  Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
481  that was filled.
482 ****************************************************************************/
483
484 static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
485         connection_struct *conn, struct ea_list *ea_list)
486 {
487         unsigned int ret_data_size = 4;
488         char *p = pdata;
489
490         SMB_ASSERT(total_data_size >= 4);
491
492         if (!lp_ea_support(SNUM(conn))) {
493                 SIVAL(pdata,4,0);
494                 return 4;
495         }
496
497         for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
498                 size_t dos_namelen;
499                 fstring dos_ea_name;
500                 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
501                 dos_namelen = strlen(dos_ea_name);
502                 if (dos_namelen > 255 || dos_namelen == 0) {
503                         break;
504                 }
505                 if (ea_list->ea.value.length > 65535) {
506                         break;
507                 }
508                 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
509                         break;
510                 }
511
512                 /* We know we have room. */
513                 SCVAL(p,0,ea_list->ea.flags);
514                 SCVAL(p,1,dos_namelen);
515                 SSVAL(p,2,ea_list->ea.value.length);
516                 strlcpy(p+4, dos_ea_name, dos_namelen+1);
517                 if (ea_list->ea.value.length > 0) {
518                         memcpy(p + 4 + dos_namelen + 1,
519                                ea_list->ea.value.data,
520                                ea_list->ea.value.length);
521                 }
522
523                 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
524                 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
525         }
526
527         ret_data_size = PTR_DIFF(p, pdata);
528         DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
529         SIVAL(pdata,0,ret_data_size);
530         return ret_data_size;
531 }
532
533 static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
534                                        char *pdata,
535                                        unsigned int total_data_size,
536                                        unsigned int *ret_data_size,
537                                        connection_struct *conn,
538                                        struct ea_list *ea_list)
539 {
540         uint8_t *p = (uint8_t *)pdata;
541         uint8_t *last_start = NULL;
542         bool do_store_data = (pdata != NULL);
543
544         *ret_data_size = 0;
545
546         if (!lp_ea_support(SNUM(conn))) {
547                 return NT_STATUS_NO_EAS_ON_FILE;
548         }
549
550         for (; ea_list; ea_list = ea_list->next) {
551                 size_t dos_namelen;
552                 fstring dos_ea_name;
553                 size_t this_size;
554                 size_t pad = 0;
555
556                 if (last_start != NULL && do_store_data) {
557                         SIVAL(last_start, 0, PTR_DIFF(p, last_start));
558                 }
559                 last_start = p;
560
561                 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
562                 dos_namelen = strlen(dos_ea_name);
563                 if (dos_namelen > 255 || dos_namelen == 0) {
564                         return NT_STATUS_INTERNAL_ERROR;
565                 }
566                 if (ea_list->ea.value.length > 65535) {
567                         return NT_STATUS_INTERNAL_ERROR;
568                 }
569
570                 this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length;
571
572                 if (ea_list->next) {
573                         pad = (4 - (this_size % 4)) % 4;
574                         this_size += pad;
575                 }
576
577                 if (do_store_data) {
578                         if (this_size > total_data_size) {
579                                 return NT_STATUS_INFO_LENGTH_MISMATCH;
580                         }
581
582                         /* We know we have room. */
583                         SIVAL(p, 0x00, 0); /* next offset */
584                         SCVAL(p, 0x04, ea_list->ea.flags);
585                         SCVAL(p, 0x05, dos_namelen);
586                         SSVAL(p, 0x06, ea_list->ea.value.length);
587                         strlcpy((char *)(p+0x08), dos_ea_name, dos_namelen+1);
588                         memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
589                         if (pad) {
590                                 memset(p + 0x08 + dos_namelen + 1 + ea_list->ea.value.length,
591                                         '\0',
592                                         pad);
593                         }
594                         total_data_size -= this_size;
595                 }
596
597                 p += this_size;
598         }
599
600         *ret_data_size = PTR_DIFF(p, pdata);
601         DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size));
602         return NT_STATUS_OK;
603 }
604
605 unsigned int estimate_ea_size(files_struct *fsp)
606 {
607         size_t total_ea_len = 0;
608         TALLOC_CTX *mem_ctx;
609         struct ea_list *ea_list = NULL;
610         NTSTATUS status;
611
612         /* symlink */
613         if (fsp == NULL) {
614                 return 0;
615         }
616
617         if (!lp_ea_support(SNUM(fsp->conn))) {
618                 return 0;
619         }
620
621         mem_ctx = talloc_stackframe();
622
623         /* If this is a stream fsp, then we need to instead find the
624          * estimated ea len from the main file, not the stream
625          * (streams cannot have EAs), but the estimate isn't just 0 in
626          * this case! */
627         fsp = metadata_fsp(fsp);
628         (void)get_ea_list_from_fsp(mem_ctx,
629                                    fsp,
630                                    &total_ea_len,
631                                    &ea_list);
632
633         if(fsp->conn->sconn->using_smb2) {
634                 unsigned int ret_data_size;
635                 /*
636                  * We're going to be using fill_ea_chained_buffer() to
637                  * marshall EA's - this size is significantly larger
638                  * than the SMB1 buffer. Re-calculate the size without
639                  * marshalling.
640                  */
641                 status = fill_ea_chained_buffer(mem_ctx,
642                                                 NULL,
643                                                 0,
644                                                 &ret_data_size,
645                                                 fsp->conn,
646                                                 ea_list);
647                 if (!NT_STATUS_IS_OK(status)) {
648                         ret_data_size = 0;
649                 }
650                 total_ea_len = ret_data_size;
651         }
652         TALLOC_FREE(mem_ctx);
653         return total_ea_len;
654 }
655
656 /****************************************************************************
657  Ensure the EA name is case insensitive by matching any existing EA name.
658 ****************************************************************************/
659
660 static void canonicalize_ea_name(files_struct *fsp,
661                         fstring unix_ea_name)
662 {
663         size_t total_ea_len;
664         TALLOC_CTX *mem_ctx = talloc_tos();
665         struct ea_list *ea_list;
666         NTSTATUS status = get_ea_list_from_fsp(mem_ctx,
667                                                fsp,
668                                                &total_ea_len,
669                                                &ea_list);
670         if (!NT_STATUS_IS_OK(status)) {
671                 return;
672         }
673
674         for (; ea_list; ea_list = ea_list->next) {
675                 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
676                         DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
677                                 &unix_ea_name[5], ea_list->ea.name));
678                         strlcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-5);
679                         break;
680                 }
681         }
682 }
683
684 /****************************************************************************
685  Set or delete an extended attribute.
686 ****************************************************************************/
687
688 NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
689                 struct ea_list *ea_list)
690 {
691         NTSTATUS status;
692         bool posix_pathnames = false;
693
694         if (!lp_ea_support(SNUM(conn))) {
695                 return NT_STATUS_EAS_NOT_SUPPORTED;
696         }
697
698         if (fsp == NULL) {
699                 return NT_STATUS_INVALID_HANDLE;
700         }
701
702         posix_pathnames = (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
703
704         status = refuse_symlink_fsp(fsp);
705         if (!NT_STATUS_IS_OK(status)) {
706                 return status;
707         }
708
709         status = check_any_access_fsp(fsp, FILE_WRITE_EA);
710         if (!NT_STATUS_IS_OK(status)) {
711                 return status;
712         }
713
714         /* Setting EAs on streams isn't supported. */
715         if (fsp_is_alternate_stream(fsp)) {
716                 return NT_STATUS_INVALID_PARAMETER;
717         }
718
719         /*
720          * Filter out invalid Windows EA names - before
721          * we set *any* of them.
722          */
723
724         if (!posix_pathnames && ea_list_has_invalid_name(ea_list)) {
725                 return STATUS_INVALID_EA_NAME;
726         }
727
728         for (;ea_list; ea_list = ea_list->next) {
729                 int ret;
730                 fstring unix_ea_name;
731
732                 /*
733                  * Complementing the forward mapping from POSIX EAs to
734                  * Windows EAs in get_ea_list_from_fsp(), here we map in the
735                  * opposite direction from Windows EAs to the 'user' namespace
736                  * of POSIX EAs. Hence, all POSIX EA names the we set here must
737                  * start with a 'user.' prefix.
738                  */
739                 fstrcpy(unix_ea_name, "user.");
740                 fstrcat(unix_ea_name, ea_list->ea.name);
741
742                 canonicalize_ea_name(fsp, unix_ea_name);
743
744                 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
745
746                 if (samba_private_attr_name(unix_ea_name)) {
747                         DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
748                         return NT_STATUS_ACCESS_DENIED;
749                 }
750
751                 if (ea_list->ea.value.length == 0) {
752                         /* Remove the attribute. */
753                         DBG_DEBUG("deleting ea name %s on "
754                                   "file %s by file descriptor.\n",
755                                   unix_ea_name, fsp_str_dbg(fsp));
756                         ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
757 #ifdef ENOATTR
758                         /* Removing a non existent attribute always succeeds. */
759                         if (ret == -1 && errno == ENOATTR) {
760                                 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
761                                                 unix_ea_name));
762                                 ret = 0;
763                         }
764 #endif
765                 } else {
766                         DEBUG(10,("set_ea: setting ea name %s on file "
767                                   "%s by file descriptor.\n",
768                                   unix_ea_name, fsp_str_dbg(fsp)));
769                         ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
770                                                 ea_list->ea.value.data, ea_list->ea.value.length, 0);
771                 }
772
773                 if (ret == -1) {
774 #ifdef ENOTSUP
775                         if (errno == ENOTSUP) {
776                                 return NT_STATUS_EAS_NOT_SUPPORTED;
777                         }
778 #endif
779                         return map_nt_error_from_unix(errno);
780                 }
781
782         }
783         return NT_STATUS_OK;
784 }
785
786 /****************************************************************************
787  Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
788 ****************************************************************************/
789
790 struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
791 {
792         struct ea_list *ea_list_head = NULL;
793         size_t offset = 0;
794         size_t bytes_used = 0;
795
796         while (offset < data_size) {
797                 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
798
799                 if (!eal) {
800                         return NULL;
801                 }
802
803                 DLIST_ADD_END(ea_list_head, eal);
804                 offset += bytes_used;
805         }
806
807         return ea_list_head;
808 }
809
810 /****************************************************************************
811  Count the total EA size needed.
812 ****************************************************************************/
813
814 static size_t ea_list_size(struct ea_list *ealist)
815 {
816         fstring dos_ea_name;
817         struct ea_list *listp;
818         size_t ret = 0;
819
820         for (listp = ealist; listp; listp = listp->next) {
821                 push_ascii_fstring(dos_ea_name, listp->ea.name);
822                 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
823         }
824         /* Add on 4 for total length. */
825         if (ret) {
826                 ret += 4;
827         }
828
829         return ret;
830 }
831
832 /****************************************************************************
833  Return a union of EA's from a file list and a list of names.
834  The TALLOC context for the two lists *MUST* be identical as we steal
835  memory from one list to add to another. JRA.
836 ****************************************************************************/
837
838 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
839 {
840         struct ea_list *nlistp, *flistp;
841
842         for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
843                 for (flistp = file_list; flistp; flistp = flistp->next) {
844                         if (strequal(nlistp->ea.name, flistp->ea.name)) {
845                                 break;
846                         }
847                 }
848
849                 if (flistp) {
850                         /* Copy the data from this entry. */
851                         nlistp->ea.flags = flistp->ea.flags;
852                         nlistp->ea.value = flistp->ea.value;
853                 } else {
854                         /* Null entry. */
855                         nlistp->ea.flags = 0;
856                         ZERO_STRUCT(nlistp->ea.value);
857                 }
858         }
859
860         *total_ea_len = ea_list_size(name_list);
861         return name_list;
862 }
863
864 /****************************************************************************
865  Return the filetype for UNIX extensions.
866 ****************************************************************************/
867
868 static uint32_t unix_filetype(mode_t mode)
869 {
870         if(S_ISREG(mode))
871                 return UNIX_TYPE_FILE;
872         else if(S_ISDIR(mode))
873                 return UNIX_TYPE_DIR;
874 #ifdef S_ISLNK
875         else if(S_ISLNK(mode))
876                 return UNIX_TYPE_SYMLINK;
877 #endif
878 #ifdef S_ISCHR
879         else if(S_ISCHR(mode))
880                 return UNIX_TYPE_CHARDEV;
881 #endif
882 #ifdef S_ISBLK
883         else if(S_ISBLK(mode))
884                 return UNIX_TYPE_BLKDEV;
885 #endif
886 #ifdef S_ISFIFO
887         else if(S_ISFIFO(mode))
888                 return UNIX_TYPE_FIFO;
889 #endif
890 #ifdef S_ISSOCK
891         else if(S_ISSOCK(mode))
892                 return UNIX_TYPE_SOCKET;
893 #endif
894
895         DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
896         return UNIX_TYPE_UNKNOWN;
897 }
898
899 /****************************************************************************
900  Map wire perms onto standard UNIX permissions. Obey share restrictions.
901 ****************************************************************************/
902
903 NTSTATUS unix_perms_from_wire(connection_struct *conn,
904                               const SMB_STRUCT_STAT *psbuf,
905                               uint32_t perms,
906                               enum perm_type ptype,
907                               mode_t *ret_perms)
908 {
909         mode_t ret = 0;
910
911         if (perms == SMB_MODE_NO_CHANGE) {
912                 if (!VALID_STAT(*psbuf)) {
913                         return NT_STATUS_INVALID_PARAMETER;
914                 } else {
915                         *ret_perms = psbuf->st_ex_mode;
916                         return NT_STATUS_OK;
917                 }
918         }
919
920         ret = wire_perms_to_unix(perms);
921
922         if (ptype == PERM_NEW_FILE) {
923                 /*
924                  * "create mask"/"force create mode" are
925                  * only applied to new files, not existing ones.
926                  */
927                 ret &= lp_create_mask(SNUM(conn));
928                 /* Add in force bits */
929                 ret |= lp_force_create_mode(SNUM(conn));
930         } else if (ptype == PERM_NEW_DIR) {
931                 /*
932                  * "directory mask"/"force directory mode" are
933                  * only applied to new directories, not existing ones.
934                  */
935                 ret &= lp_directory_mask(SNUM(conn));
936                 /* Add in force bits */
937                 ret |= lp_force_directory_mode(SNUM(conn));
938         }
939
940         *ret_perms = ret;
941         return NT_STATUS_OK;
942 }
943
944 /****************************************************************************
945  Get a level dependent lanman2 dir entry.
946 ****************************************************************************/
947
948 struct smbd_dirptr_lanman2_state {
949         connection_struct *conn;
950         uint32_t info_level;
951         bool check_mangled_names;
952         bool case_sensitive;
953 };
954
955 static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX *ctx,
956                                          void *private_data,
957                                          const char *dname,
958                                          const char *mask,
959                                          char **_fname)
960 {
961         struct smbd_dirptr_lanman2_state *state =
962                 (struct smbd_dirptr_lanman2_state *)private_data;
963         bool ok;
964         char mangled_name[13]; /* mangled 8.3 name. */
965         bool got_match;
966         const char *fname;
967
968         /* Mangle fname if it's an illegal name. */
969         if (mangle_must_mangle(dname, state->conn->params)) {
970                 /*
971                  * Slow path - ensure we can push the original name as UCS2. If
972                  * not, then just don't return this name.
973                  */
974                 NTSTATUS status;
975                 size_t ret_len = 0;
976                 size_t len = (strlen(dname) + 2) * 4; /* Allow enough space. */
977                 uint8_t *tmp = talloc_array(talloc_tos(),
978                                         uint8_t,
979                                         len);
980
981                 status = srvstr_push(NULL,
982                         FLAGS2_UNICODE_STRINGS,
983                         tmp,
984                         dname,
985                         len,
986                         STR_TERMINATE,
987                         &ret_len);
988
989                 TALLOC_FREE(tmp);
990
991                 if (!NT_STATUS_IS_OK(status)) {
992                         return false;
993                 }
994
995                 ok = name_to_8_3(dname, mangled_name,
996                                  true, state->conn->params);
997                 if (!ok) {
998                         return false;
999                 }
1000                 fname = mangled_name;
1001         } else {
1002                 fname = dname;
1003         }
1004
1005         got_match = mask_match(fname, mask,
1006                                state->case_sensitive);
1007
1008         if(!got_match && state->check_mangled_names &&
1009            !mangle_is_8_3(fname, false, state->conn->params)) {
1010                 /*
1011                  * It turns out that NT matches wildcards against
1012                  * both long *and* short names. This may explain some
1013                  * of the wildcard weirdness from old DOS clients
1014                  * that some people have been seeing.... JRA.
1015                  */
1016                 /* Force the mangling into 8.3. */
1017                 ok = name_to_8_3(fname, mangled_name,
1018                                  false, state->conn->params);
1019                 if (!ok) {
1020                         return false;
1021                 }
1022
1023                 got_match = mask_match(mangled_name, mask,
1024                                        state->case_sensitive);
1025         }
1026
1027         if (!got_match) {
1028                 return false;
1029         }
1030
1031         *_fname = talloc_strdup(ctx, fname);
1032         if (*_fname == NULL) {
1033                 return false;
1034         }
1035
1036         return true;
1037 }
1038
1039 static uint32_t get_dirent_ea_size(uint32_t mode, files_struct *fsp)
1040 {
1041         if (!(mode & FILE_ATTRIBUTE_REPARSE_POINT)) {
1042                 unsigned ea_size = estimate_ea_size(fsp);
1043                 return ea_size;
1044         }
1045         return IO_REPARSE_TAG_DFS;
1046 }
1047
1048 static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
1049                                     connection_struct *conn,
1050                                     uint16_t flags2,
1051                                     uint32_t info_level,
1052                                     struct ea_list *name_list,
1053                                     bool check_mangled_names,
1054                                     bool requires_resume_key,
1055                                     uint32_t mode,
1056                                     const char *fname,
1057                                     const struct smb_filename *smb_fname,
1058                                     int space_remaining,
1059                                     uint8_t align,
1060                                     bool do_pad,
1061                                     char *base_data,
1062                                     char **ppdata,
1063                                     char *end_data,
1064                                     uint64_t *last_entry_off)
1065 {
1066         char *p, *q, *pdata = *ppdata;
1067         uint32_t reskey=0;
1068         uint64_t file_size = 0;
1069         uint64_t allocation_size = 0;
1070         uint64_t file_id = 0;
1071         size_t len = 0;
1072         struct timespec mdate_ts = {0};
1073         struct timespec adate_ts = {0};
1074         struct timespec cdate_ts = {0};
1075         struct timespec create_date_ts = {0};
1076         char *nameptr;
1077         char *last_entry_ptr;
1078         bool was_8_3;
1079         int off;
1080         int pad = 0;
1081         NTSTATUS status;
1082         struct readdir_attr_data *readdir_attr_data = NULL;
1083         uint32_t ea_size;
1084
1085         if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
1086                 file_size = get_file_size_stat(&smb_fname->st);
1087         }
1088         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
1089
1090         /*
1091          * Skip SMB_VFS_FREADDIR_ATTR if the directory entry is a symlink or
1092          * a DFS symlink.
1093          */
1094         if (smb_fname->fsp != NULL &&
1095             !(mode & FILE_ATTRIBUTE_REPARSE_POINT)) {
1096                 status = SMB_VFS_FREADDIR_ATTR(smb_fname->fsp,
1097                                                ctx,
1098                                                &readdir_attr_data);
1099                 if (!NT_STATUS_IS_OK(status)) {
1100                         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_SUPPORTED,
1101                                              status)) {
1102                                 return status;
1103                         }
1104                 }
1105         }
1106
1107         file_id = SMB_VFS_FS_FILE_ID(conn, &smb_fname->st);
1108
1109         mdate_ts = smb_fname->st.st_ex_mtime;
1110         adate_ts = smb_fname->st.st_ex_atime;
1111         create_date_ts = get_create_timespec(conn, NULL, smb_fname);
1112         cdate_ts = get_change_timespec(conn, NULL, smb_fname);
1113
1114         if (lp_dos_filetime_resolution(SNUM(conn))) {
1115                 dos_filetime_timespec(&create_date_ts);
1116                 dos_filetime_timespec(&mdate_ts);
1117                 dos_filetime_timespec(&adate_ts);
1118                 dos_filetime_timespec(&cdate_ts);
1119         }
1120
1121         /* align the record */
1122         SMB_ASSERT(align >= 1);
1123
1124         off = (int)PTR_DIFF(pdata, base_data);
1125         pad = (off + (align-1)) & ~(align-1);
1126         pad -= off;
1127
1128         if (pad && pad > space_remaining) {
1129                 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1130                         "for padding (wanted %u, had %d)\n",
1131                         (unsigned int)pad,
1132                         space_remaining ));
1133                 return STATUS_MORE_ENTRIES; /* Not finished - just out of space */
1134         }
1135
1136         off += pad;
1137         /* initialize padding to 0 */
1138         if (pad) {
1139                 memset(pdata, 0, pad);
1140         }
1141         space_remaining -= pad;
1142
1143         DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
1144                 space_remaining ));
1145
1146         pdata += pad;
1147         p = pdata;
1148         last_entry_ptr = p;
1149
1150         pad = 0;
1151         off = 0;
1152
1153         switch (info_level) {
1154         case SMB_FIND_INFO_STANDARD:
1155                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1156                 if(requires_resume_key) {
1157                         SIVAL(p,0,reskey);
1158                         p += 4;
1159                 }
1160                 srv_put_dos_date2_ts(p, 0, create_date_ts);
1161                 srv_put_dos_date2_ts(p, 4, adate_ts);
1162                 srv_put_dos_date2_ts(p, 8, mdate_ts);
1163                 SIVAL(p,12,(uint32_t)file_size);
1164                 SIVAL(p,16,(uint32_t)allocation_size);
1165                 SSVAL(p,20,mode);
1166                 p += 23;
1167                 nameptr = p;
1168                 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1169                         p += ucs2_align(base_data, p, 0);
1170                 }
1171                 status = srvstr_push(base_data, flags2, p,
1172                                   fname, PTR_DIFF(end_data, p),
1173                                   STR_TERMINATE, &len);
1174                 if (!NT_STATUS_IS_OK(status)) {
1175                         return status;
1176                 }
1177                 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1178                         if (len > 2) {
1179                                 SCVAL(nameptr, -1, len - 2);
1180                         } else {
1181                                 SCVAL(nameptr, -1, 0);
1182                         }
1183                 } else {
1184                         if (len > 1) {
1185                                 SCVAL(nameptr, -1, len - 1);
1186                         } else {
1187                                 SCVAL(nameptr, -1, 0);
1188                         }
1189                 }
1190                 p += len;
1191                 break;
1192
1193         case SMB_FIND_EA_SIZE:
1194                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
1195                 if (requires_resume_key) {
1196                         SIVAL(p,0,reskey);
1197                         p += 4;
1198                 }
1199                 srv_put_dos_date2_ts(p, 0, create_date_ts);
1200                 srv_put_dos_date2_ts(p, 4, adate_ts);
1201                 srv_put_dos_date2_ts(p, 8, mdate_ts);
1202                 SIVAL(p,12,(uint32_t)file_size);
1203                 SIVAL(p,16,(uint32_t)allocation_size);
1204                 SSVAL(p,20,mode);
1205                 {
1206                         ea_size = estimate_ea_size(smb_fname->fsp);
1207                         SIVAL(p,22,ea_size); /* Extended attributes */
1208                 }
1209                 p += 27;
1210                 nameptr = p - 1;
1211                 status = srvstr_push(base_data, flags2,
1212                                   p, fname, PTR_DIFF(end_data, p),
1213                                   STR_TERMINATE | STR_NOALIGN, &len);
1214                 if (!NT_STATUS_IS_OK(status)) {
1215                         return status;
1216                 }
1217                 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1218                         if (len > 2) {
1219                                 len -= 2;
1220                         } else {
1221                                 len = 0;
1222                         }
1223                 } else {
1224                         if (len > 1) {
1225                                 len -= 1;
1226                         } else {
1227                                 len = 0;
1228                         }
1229                 }
1230                 SCVAL(nameptr,0,len);
1231                 p += len;
1232                 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1233                 break;
1234
1235         case SMB_FIND_EA_LIST:
1236         {
1237                 struct ea_list *file_list = NULL;
1238                 size_t ea_len = 0;
1239
1240                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
1241                 if (!name_list) {
1242                         return NT_STATUS_INVALID_PARAMETER;
1243                 }
1244                 if (requires_resume_key) {
1245                         SIVAL(p,0,reskey);
1246                         p += 4;
1247                 }
1248                 srv_put_dos_date2_ts(p, 0, create_date_ts);
1249                 srv_put_dos_date2_ts(p, 4, adate_ts);
1250                 srv_put_dos_date2_ts(p, 8, mdate_ts);
1251                 SIVAL(p,12,(uint32_t)file_size);
1252                 SIVAL(p,16,(uint32_t)allocation_size);
1253                 SSVAL(p,20,mode);
1254                 p += 22; /* p now points to the EA area. */
1255
1256                 status = get_ea_list_from_fsp(ctx,
1257                                                smb_fname->fsp,
1258                                                &ea_len, &file_list);
1259                 if (!NT_STATUS_IS_OK(status)) {
1260                         file_list = NULL;
1261                 }
1262                 name_list = ea_list_union(name_list, file_list, &ea_len);
1263
1264                 /* We need to determine if this entry will fit in the space available. */
1265                 /* Max string size is 255 bytes. */
1266                 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1267                         DEBUG(9,("smbd_marshall_dir_entry: out of space "
1268                                 "(wanted %u, had %d)\n",
1269                                 (unsigned int)PTR_DIFF(p + 255 + ea_len,pdata),
1270                                 space_remaining ));
1271                         return STATUS_MORE_ENTRIES; /* Not finished - just out of space */
1272                 }
1273
1274                 /* Push the ea_data followed by the name. */
1275                 p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
1276                 nameptr = p;
1277                 status = srvstr_push(base_data, flags2,
1278                                   p + 1, fname, PTR_DIFF(end_data, p+1),
1279                                   STR_TERMINATE | STR_NOALIGN, &len);
1280                 if (!NT_STATUS_IS_OK(status)) {
1281                         return status;
1282                 }
1283                 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1284                         if (len > 2) {
1285                                 len -= 2;
1286                         } else {
1287                                 len = 0;
1288                         }
1289                 } else {
1290                         if (len > 1) {
1291                                 len -= 1;
1292                         } else {
1293                                 len = 0;
1294                         }
1295                 }
1296                 SCVAL(nameptr,0,len);
1297                 p += len + 1;
1298                 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1299                 break;
1300         }
1301
1302         case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1303                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1304                 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1305                 p += 4;
1306                 SIVAL(p,0,reskey); p += 4;
1307                 put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
1308                 put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
1309                 put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
1310                 put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
1311                 SOFF_T(p,0,file_size); p += 8;
1312                 SOFF_T(p,0,allocation_size); p += 8;
1313                 SIVAL(p,0,mode); p += 4;
1314                 q = p; p += 4; /* q is placeholder for name length. */
1315                 ea_size = get_dirent_ea_size(mode, smb_fname->fsp);
1316                 SIVAL(p, 0, ea_size);
1317                 p += 4;
1318                 /* Clear the short name buffer. This is
1319                  * IMPORTANT as not doing so will trigger
1320                  * a Win2k client bug. JRA.
1321                  */
1322                 if (!was_8_3 && check_mangled_names) {
1323                         char mangled_name[13]; /* mangled 8.3 name. */
1324                         if (!name_to_8_3(fname,mangled_name,True,
1325                                            conn->params)) {
1326                                 /* Error - mangle failed ! */
1327                                 memset(mangled_name,'\0',12);
1328                         }
1329                         mangled_name[12] = 0;
1330                         status = srvstr_push(base_data, flags2,
1331                                           p+2, mangled_name, 24,
1332                                           STR_UPPER|STR_UNICODE, &len);
1333                         if (!NT_STATUS_IS_OK(status)) {
1334                                 return status;
1335                         }
1336                         if (len < 24) {
1337                                 memset(p + 2 + len,'\0',24 - len);
1338                         }
1339                         SSVAL(p, 0, len);
1340                 } else {
1341                         memset(p,'\0',26);
1342                 }
1343                 p += 2 + 24;
1344                 status = srvstr_push(base_data, flags2, p,
1345                                   fname, PTR_DIFF(end_data, p),
1346                                   STR_TERMINATE_ASCII, &len);
1347                 if (!NT_STATUS_IS_OK(status)) {
1348                         return status;
1349                 }
1350                 SIVAL(q,0,len);
1351                 p += len;
1352
1353                 len = PTR_DIFF(p, pdata);
1354                 pad = (len + (align-1)) & ~(align-1);
1355                 /*
1356                  * offset to the next entry, the caller
1357                  * will overwrite it for the last entry
1358                  * that's why we always include the padding
1359                  */
1360                 SIVAL(pdata,0,pad);
1361                 /*
1362                  * set padding to zero
1363                  */
1364                 if (do_pad) {
1365                         memset(p, 0, pad - len);
1366                         p = pdata + pad;
1367                 } else {
1368                         p = pdata + len;
1369                 }
1370                 break;
1371
1372         case SMB_FIND_FILE_DIRECTORY_INFO:
1373                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1374                 p += 4;
1375                 SIVAL(p,0,reskey); p += 4;
1376                 put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
1377                 put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
1378                 put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
1379                 put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
1380                 SOFF_T(p,0,file_size); p += 8;
1381                 SOFF_T(p,0,allocation_size); p += 8;
1382                 SIVAL(p,0,mode); p += 4;
1383                 status = srvstr_push(base_data, flags2,
1384                                   p + 4, fname, PTR_DIFF(end_data, p+4),
1385                                   STR_TERMINATE_ASCII, &len);
1386                 if (!NT_STATUS_IS_OK(status)) {
1387                         return status;
1388                 }
1389                 SIVAL(p,0,len);
1390                 p += 4 + len;
1391
1392                 len = PTR_DIFF(p, pdata);
1393                 pad = (len + (align-1)) & ~(align-1);
1394                 /*
1395                  * offset to the next entry, the caller
1396                  * will overwrite it for the last entry
1397                  * that's why we always include the padding
1398                  */
1399                 SIVAL(pdata,0,pad);
1400                 /*
1401                  * set padding to zero
1402                  */
1403                 if (do_pad) {
1404                         memset(p, 0, pad - len);
1405                         p = pdata + pad;
1406                 } else {
1407                         p = pdata + len;
1408                 }
1409                 break;
1410
1411         case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1412                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1413                 p += 4;
1414                 SIVAL(p,0,reskey); p += 4;
1415                 put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
1416                 put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
1417                 put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
1418                 put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
1419                 SOFF_T(p,0,file_size); p += 8;
1420                 SOFF_T(p,0,allocation_size); p += 8;
1421                 SIVAL(p,0,mode); p += 4;
1422                 q = p; p += 4; /* q is placeholder for name length. */
1423                 ea_size = get_dirent_ea_size(mode, smb_fname->fsp);
1424                 SIVAL(p, 0, ea_size);
1425                 p +=4;
1426                 status = srvstr_push(base_data, flags2, p,
1427                                   fname, PTR_DIFF(end_data, p),
1428                                   STR_TERMINATE_ASCII, &len);
1429                 if (!NT_STATUS_IS_OK(status)) {
1430                         return status;
1431                 }
1432                 SIVAL(q, 0, len);
1433                 p += len;
1434
1435                 len = PTR_DIFF(p, pdata);
1436                 pad = (len + (align-1)) & ~(align-1);
1437                 /*
1438                  * offset to the next entry, the caller
1439                  * will overwrite it for the last entry
1440                  * that's why we always include the padding
1441                  */
1442                 SIVAL(pdata,0,pad);
1443                 /*
1444                  * set padding to zero
1445                  */
1446                 if (do_pad) {
1447                         memset(p, 0, pad - len);
1448                         p = pdata + pad;
1449                 } else {
1450                         p = pdata + len;
1451                 }
1452                 break;
1453
1454         case SMB_FIND_FILE_NAMES_INFO:
1455                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1456                 p += 4;
1457                 SIVAL(p,0,reskey); p += 4;
1458                 p += 4;
1459                 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1460                    acl on a dir (tridge) */
1461                 status = srvstr_push(base_data, flags2, p,
1462                                   fname, PTR_DIFF(end_data, p),
1463                                   STR_TERMINATE_ASCII, &len);
1464                 if (!NT_STATUS_IS_OK(status)) {
1465                         return status;
1466                 }
1467                 SIVAL(p, -4, len);
1468                 p += len;
1469
1470                 len = PTR_DIFF(p, pdata);
1471                 pad = (len + (align-1)) & ~(align-1);
1472                 /*
1473                  * offset to the next entry, the caller
1474                  * will overwrite it for the last entry
1475                  * that's why we always include the padding
1476                  */
1477                 SIVAL(pdata,0,pad);
1478                 /*
1479                  * set padding to zero
1480                  */
1481                 if (do_pad) {
1482                         memset(p, 0, pad - len);
1483                         p = pdata + pad;
1484                 } else {
1485                         p = pdata + len;
1486                 }
1487                 break;
1488
1489         case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1490                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1491                 p += 4;
1492                 SIVAL(p,0,reskey); p += 4;
1493                 put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
1494                 put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
1495                 put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
1496                 put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
1497                 SOFF_T(p,0,file_size); p += 8;
1498                 SOFF_T(p,0,allocation_size); p += 8;
1499                 SIVAL(p,0,mode); p += 4;
1500                 q = p; p += 4; /* q is placeholder for name length. */
1501                 ea_size = get_dirent_ea_size(mode, smb_fname->fsp);
1502                 SIVAL(p, 0, ea_size);
1503                 p += 4;
1504                 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1505                 SBVAL(p,0,file_id); p += 8;
1506                 status = srvstr_push(base_data, flags2, p,
1507                                   fname, PTR_DIFF(end_data, p),
1508                                   STR_TERMINATE_ASCII, &len);
1509                 if (!NT_STATUS_IS_OK(status)) {
1510                         return status;
1511                 }
1512                 SIVAL(q, 0, len);
1513                 p += len;
1514
1515                 len = PTR_DIFF(p, pdata);
1516                 pad = (len + (align-1)) & ~(align-1);
1517                 /*
1518                  * offset to the next entry, the caller
1519                  * will overwrite it for the last entry
1520                  * that's why we always include the padding
1521                  */
1522                 SIVAL(pdata,0,pad);
1523                 /*
1524                  * set padding to zero
1525                  */
1526                 if (do_pad) {
1527                         memset(p, 0, pad - len);
1528                         p = pdata + pad;
1529                 } else {
1530                         p = pdata + len;
1531                 }
1532                 break;
1533
1534         case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1535                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1536                 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1537                 p += 4;
1538                 SIVAL(p,0,reskey); p += 4;
1539                 put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
1540                 put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
1541                 put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
1542                 put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
1543                 SOFF_T(p,0,file_size); p += 8;
1544                 SOFF_T(p,0,allocation_size); p += 8;
1545                 SIVAL(p,0,mode); p += 4;
1546                 q = p; p += 4; /* q is placeholder for name length */
1547                 if (readdir_attr_data &&
1548                     readdir_attr_data->type == RDATTR_AAPL) {
1549                         /*
1550                          * OS X specific SMB2 extension negotiated via
1551                          * AAPL create context: return max_access in
1552                          * ea_size field.
1553                          */
1554                         ea_size = readdir_attr_data->attr_data.aapl.max_access;
1555                 } else {
1556                         ea_size = get_dirent_ea_size(mode, smb_fname->fsp);
1557                 }
1558                 SIVAL(p,0,ea_size); /* Extended attributes */
1559                 p += 4;
1560
1561                 if (readdir_attr_data &&
1562                     readdir_attr_data->type == RDATTR_AAPL) {
1563                         /*
1564                          * OS X specific SMB2 extension negotiated via
1565                          * AAPL create context: return resource fork
1566                          * length and compressed FinderInfo in
1567                          * shortname field.
1568                          *
1569                          * According to documentation short_name_len
1570                          * should be 0, but on the wire behaviour
1571                          * shows its set to 24 by clients.
1572                          */
1573                         SSVAL(p, 0, 24);
1574
1575                         /* Resourefork length */
1576                         SBVAL(p, 2, readdir_attr_data->attr_data.aapl.rfork_size);
1577
1578                         /* Compressed FinderInfo */
1579                         memcpy(p + 10, &readdir_attr_data->attr_data.aapl.finder_info, 16);
1580                 } else if (!was_8_3 && check_mangled_names) {
1581                         char mangled_name[13]; /* mangled 8.3 name. */
1582                         if (!name_to_8_3(fname,mangled_name,True,
1583                                         conn->params)) {
1584                                 /* Error - mangle failed ! */
1585                                 memset(mangled_name,'\0',12);
1586                         }
1587                         mangled_name[12] = 0;
1588                         status = srvstr_push(base_data, flags2,
1589                                           p+2, mangled_name, 24,
1590                                           STR_UPPER|STR_UNICODE, &len);
1591                         if (!NT_STATUS_IS_OK(status)) {
1592                                 return status;
1593                         }
1594                         SSVAL(p, 0, len);
1595                         if (len < 24) {
1596                                 memset(p + 2 + len,'\0',24 - len);
1597                         }
1598                         SSVAL(p, 0, len);
1599                 } else {
1600                         /* Clear the short name buffer. This is
1601                          * IMPORTANT as not doing so will trigger
1602                          * a Win2k client bug. JRA.
1603                          */
1604                         memset(p,'\0',26);
1605                 }
1606                 p += 26;
1607
1608                 /* Reserved ? */
1609                 if (readdir_attr_data &&
1610                     readdir_attr_data->type == RDATTR_AAPL) {
1611                         /*
1612                          * OS X specific SMB2 extension negotiated via
1613                          * AAPL create context: return UNIX mode in
1614                          * reserved field.
1615                          */
1616                         uint16_t aapl_mode = (uint16_t)readdir_attr_data->attr_data.aapl.unix_mode;
1617                         SSVAL(p, 0, aapl_mode);
1618                 } else {
1619                         SSVAL(p, 0, 0);
1620                 }
1621                 p += 2;
1622
1623                 SBVAL(p,0,file_id); p += 8;
1624                 status = srvstr_push(base_data, flags2, p,
1625                                   fname, PTR_DIFF(end_data, p),
1626                                   STR_TERMINATE_ASCII, &len);
1627                 if (!NT_STATUS_IS_OK(status)) {
1628                         return status;
1629                 }
1630                 SIVAL(q,0,len);
1631                 p += len;
1632
1633                 len = PTR_DIFF(p, pdata);
1634                 pad = (len + (align-1)) & ~(align-1);
1635                 /*
1636                  * offset to the next entry, the caller
1637                  * will overwrite it for the last entry
1638                  * that's why we always include the padding
1639                  */
1640                 SIVAL(pdata,0,pad);
1641                 /*
1642                  * set padding to zero
1643                  */
1644                 if (do_pad) {
1645                         memset(p, 0, pad - len);
1646                         p = pdata + pad;
1647                 } else {
1648                         p = pdata + len;
1649                 }
1650                 break;
1651
1652         /* CIFS UNIX Extension. */
1653
1654         case SMB_FIND_FILE_UNIX:
1655         case SMB_FIND_FILE_UNIX_INFO2:
1656                 p+= 4;
1657                 SIVAL(p,0,reskey); p+= 4;    /* Used for continuing search. */
1658
1659                 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1660
1661                 if (info_level == SMB_FIND_FILE_UNIX) {
1662                         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
1663                         p = store_file_unix_basic(conn, p,
1664                                                 NULL, &smb_fname->st);
1665                         status = srvstr_push(base_data, flags2, p,
1666                                           fname, PTR_DIFF(end_data, p),
1667                                           STR_TERMINATE, &len);
1668                         if (!NT_STATUS_IS_OK(status)) {
1669                                 return status;
1670                         }
1671                 } else {
1672                         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
1673                         p = store_file_unix_basic_info2(conn, p,
1674                                                 NULL, &smb_fname->st);
1675                         nameptr = p;
1676                         p += 4;
1677                         status = srvstr_push(base_data, flags2, p, fname,
1678                                           PTR_DIFF(end_data, p), 0, &len);
1679                         if (!NT_STATUS_IS_OK(status)) {
1680                                 return status;
1681                         }
1682                         SIVAL(nameptr, 0, len);
1683                 }
1684
1685                 p += len;
1686
1687                 len = PTR_DIFF(p, pdata);
1688                 pad = (len + (align-1)) & ~(align-1);
1689                 /*
1690                  * offset to the next entry, the caller
1691                  * will overwrite it for the last entry
1692                  * that's why we always include the padding
1693                  */
1694                 SIVAL(pdata,0,pad);
1695                 /*
1696                  * set padding to zero
1697                  */
1698                 if (do_pad) {
1699                         memset(p, 0, pad - len);
1700                         p = pdata + pad;
1701                 } else {
1702                         p = pdata + len;
1703                 }
1704                 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1705
1706                 break;
1707
1708         /* SMB2 UNIX Extension. */
1709
1710         case SMB2_FILE_POSIX_INFORMATION:
1711                 {
1712                         struct smb3_file_posix_information info = {};
1713                         uint8_t buf[sizeof(info)];
1714                         struct ndr_push ndr = {
1715                                 .data = buf,
1716                                 .alloc_size = sizeof(buf),
1717                                 .fixed_buf_size = true,
1718                         };
1719                         enum ndr_err_code ndr_err;
1720
1721                         p+= 4;
1722                         SIVAL(p,0,reskey); p+= 4;
1723
1724                         DBG_DEBUG("SMB2_FILE_POSIX_INFORMATION\n");
1725
1726                         if (!(conn->sconn->using_smb2)) {
1727                                 return NT_STATUS_INVALID_LEVEL;
1728                         }
1729
1730                         smb3_file_posix_information_init(
1731                                 conn, &smb_fname->st, 0, mode, &info);
1732
1733                         ndr_err = ndr_push_smb3_file_posix_information(
1734                                 &ndr, NDR_SCALARS|NDR_BUFFERS, &info);
1735                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1736                                 return NT_STATUS_INSUFFICIENT_RESOURCES;
1737                         }
1738
1739                         memcpy(p, buf, ndr.offset);
1740                         p += ndr.offset;
1741
1742                         nameptr = p;
1743                         p += 4;
1744                         status = srvstr_push(base_data, flags2, p, fname,
1745                                         PTR_DIFF(end_data, p), 0, &len);
1746                         if (!NT_STATUS_IS_OK(status)) {
1747                                 return status;
1748                         }
1749                         SIVAL(nameptr, 0, len);
1750
1751                         p += len;
1752
1753                         len = PTR_DIFF(p, pdata);
1754                         pad = (len + (align-1)) & ~(align-1);
1755                         /*
1756                          * offset to the next entry, the caller
1757                          * will overwrite it for the last entry
1758                          * that's why we always include the padding
1759                          */
1760                         SIVAL(pdata,0,pad);
1761                         break;
1762                 }
1763
1764         default:
1765                 return NT_STATUS_INVALID_LEVEL;
1766         }
1767
1768         if (PTR_DIFF(p,pdata) > space_remaining) {
1769                 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1770                         "(wanted %u, had %d)\n",
1771                         (unsigned int)PTR_DIFF(p,pdata),
1772                         space_remaining ));
1773                 return STATUS_MORE_ENTRIES; /* Not finished - just out of space */
1774         }
1775
1776         /* Setup the last entry pointer, as an offset from base_data */
1777         *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1778         /* Advance the data pointer to the next slot */
1779         *ppdata = p;
1780
1781         return NT_STATUS_OK;
1782 }
1783
1784 NTSTATUS smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
1785                                connection_struct *conn,
1786                                struct dptr_struct *dirptr,
1787                                uint16_t flags2,
1788                                const char *path_mask,
1789                                uint32_t dirtype,
1790                                int info_level,
1791                                int requires_resume_key,
1792                                bool dont_descend,
1793                                bool ask_sharemode,
1794                                bool get_dosmode,
1795                                uint8_t align,
1796                                bool do_pad,
1797                                char **ppdata,
1798                                char *base_data,
1799                                char *end_data,
1800                                int space_remaining,
1801                                struct smb_filename **_smb_fname,
1802                                int *_last_entry_off,
1803                                struct ea_list *name_list,
1804                                struct file_id *file_id)
1805 {
1806         const char *p;
1807         const char *mask = NULL;
1808         uint32_t mode = 0;
1809         char *fname = NULL;
1810         struct smb_filename *smb_fname = NULL;
1811         struct smbd_dirptr_lanman2_state state;
1812         bool ok;
1813         uint64_t last_entry_off = 0;
1814         NTSTATUS status;
1815         enum mangled_names_options mangled_names;
1816         bool marshall_with_83_names;
1817
1818         mangled_names = lp_mangled_names(conn->params);
1819
1820         ZERO_STRUCT(state);
1821         state.conn = conn;
1822         state.info_level = info_level;
1823         if (mangled_names != MANGLED_NAMES_NO) {
1824                 state.check_mangled_names = true;
1825         }
1826         state.case_sensitive = dptr_case_sensitive(dirptr);
1827
1828         p = strrchr_m(path_mask,'/');
1829         if(p != NULL) {
1830                 if(p[1] == '\0') {
1831                         mask = "*.*";
1832                 } else {
1833                         mask = p+1;
1834                 }
1835         } else {
1836                 mask = path_mask;
1837         }
1838
1839         ok = smbd_dirptr_get_entry(ctx,
1840                                    dirptr,
1841                                    mask,
1842                                    dirtype,
1843                                    dont_descend,
1844                                    ask_sharemode,
1845                                    get_dosmode,
1846                                    smbd_dirptr_lanman2_match_fn,
1847                                    &state,
1848                                    &fname,
1849                                    &smb_fname,
1850                                    &mode);
1851         if (!ok) {
1852                 return NT_STATUS_END_OF_FILE;
1853         }
1854
1855         marshall_with_83_names = (mangled_names == MANGLED_NAMES_YES);
1856
1857         status = smbd_marshall_dir_entry(ctx,
1858                                      conn,
1859                                      flags2,
1860                                      info_level,
1861                                      name_list,
1862                                      marshall_with_83_names,
1863                                      requires_resume_key,
1864                                      mode,
1865                                      fname,
1866                                      smb_fname,
1867                                      space_remaining,
1868                                      align,
1869                                      do_pad,
1870                                      base_data,
1871                                      ppdata,
1872                                      end_data,
1873                                      &last_entry_off);
1874         if (NT_STATUS_EQUAL(status, NT_STATUS_ILLEGAL_CHARACTER)) {
1875                 DEBUG(1,("Conversion error: illegal character: %s\n",
1876                          smb_fname_str_dbg(smb_fname)));
1877         }
1878
1879         if (file_id != NULL) {
1880                 *file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1881         }
1882
1883         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
1884                 smbd_dirptr_push_overflow(dirptr, &fname, &smb_fname, mode);
1885         }
1886
1887         if (!NT_STATUS_IS_OK(status)) {
1888                 TALLOC_FREE(smb_fname);
1889                 TALLOC_FREE(fname);
1890                 return status;
1891         }
1892
1893         smbd_dirptr_set_last_name_sent(dirptr, &smb_fname->base_name);
1894
1895         if (_smb_fname != NULL) {
1896                 /*
1897                  * smb_fname is already talloc'ed off ctx.
1898                  * We just need to make sure we don't return
1899                  * any stream_name, and replace base_name
1900                  * with fname in case base_name got mangled.
1901                  * This allows us to preserve any smb_fname->fsp
1902                  * for asynchronous handle lookups.
1903                  */
1904                 TALLOC_FREE(smb_fname->stream_name);
1905
1906                 /*
1907                  * smbd_dirptr_set_last_name_sent() above consumed
1908                  * base_name
1909                  */
1910                 smb_fname->base_name = talloc_strdup(smb_fname, fname);
1911
1912                 if (smb_fname->base_name == NULL) {
1913                         TALLOC_FREE(smb_fname);
1914                         TALLOC_FREE(fname);
1915                         return NT_STATUS_NO_MEMORY;
1916                 }
1917                 *_smb_fname = smb_fname;
1918         } else {
1919                 TALLOC_FREE(smb_fname);
1920         }
1921         TALLOC_FREE(fname);
1922
1923         *_last_entry_off = last_entry_off;
1924         return NT_STATUS_OK;
1925 }
1926
1927 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
1928 {
1929         const struct loadparm_substitution *lp_sub =
1930                 loadparm_s3_global_substitution();
1931
1932         E_md4hash(lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),objid);
1933         return objid;
1934 }
1935
1936 static void samba_extended_info_version(struct smb_extended_info *extended_info)
1937 {
1938         SMB_ASSERT(extended_info != NULL);
1939
1940         extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
1941         extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
1942                                        | ((SAMBA_VERSION_MINOR & 0xff) << 16)
1943                                        | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
1944 #ifdef SAMBA_VERSION_REVISION
1945         extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
1946 #endif
1947         extended_info->samba_subversion = 0;
1948 #ifdef SAMBA_VERSION_RC_RELEASE
1949         extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
1950 #else
1951 #ifdef SAMBA_VERSION_PRE_RELEASE
1952         extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
1953 #endif
1954 #endif
1955 #ifdef SAMBA_VERSION_VENDOR_PATCH
1956         extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
1957 #endif
1958         extended_info->samba_gitcommitdate = 0;
1959 #ifdef SAMBA_VERSION_COMMIT_TIME
1960         unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_COMMIT_TIME);
1961 #endif
1962
1963         memset(extended_info->samba_version_string, 0,
1964                sizeof(extended_info->samba_version_string));
1965
1966         snprintf (extended_info->samba_version_string,
1967                   sizeof(extended_info->samba_version_string),
1968                   "%s", samba_version_string());
1969 }
1970
1971 static bool fsinfo_unix_valid_level(connection_struct *conn,
1972                                     struct files_struct *fsp,
1973                                     uint16_t info_level)
1974 {
1975         if (conn->sconn->using_smb2 &&
1976             fsp->posix_flags == FSP_POSIX_FLAGS_OPEN &&
1977             info_level == SMB2_FS_POSIX_INFORMATION_INTERNAL)
1978         {
1979                 return true;
1980         }
1981 #if defined(SMB1SERVER)
1982         if (lp_smb1_unix_extensions() &&
1983                         info_level == SMB_QUERY_POSIX_FS_INFO) {
1984                 return true;
1985         }
1986 #endif
1987         return false;
1988 }
1989
1990 /*
1991  * fsp is only valid for SMB2.
1992  */
1993 NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
1994                          connection_struct *conn,
1995                          TALLOC_CTX *mem_ctx,
1996                          uint16_t info_level,
1997                          uint16_t flags2,
1998                          unsigned int max_data_bytes,
1999                          size_t *fixed_portion,
2000                          struct files_struct *fsp,
2001                          struct smb_filename *fname,
2002                          char **ppdata,
2003                          int *ret_data_len)
2004 {
2005         const struct loadparm_substitution *lp_sub =
2006                 loadparm_s3_global_substitution();
2007         char *pdata, *end_data;
2008         int data_len = 0;
2009         size_t len = 0;
2010         const char *vname = volume_label(talloc_tos(), SNUM(conn));
2011         int snum = SNUM(conn);
2012         const char *fstype = lp_fstype(SNUM(conn));
2013         const char *filename = NULL;
2014         const uint64_t bytes_per_sector = 512;
2015         uint32_t additional_flags = 0;
2016         struct smb_filename smb_fname;
2017         SMB_STRUCT_STAT st;
2018         NTSTATUS status = NT_STATUS_OK;
2019         uint64_t df_ret;
2020         uint32_t serial;
2021
2022         if (fname == NULL || fname->base_name == NULL) {
2023                 filename = ".";
2024         } else {
2025                 filename = fname->base_name;
2026         }
2027
2028         if (IS_IPC(conn)) {
2029                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
2030                         DEBUG(0,("smbd_do_qfsinfo: not an allowed "
2031                                 "info level (0x%x) on IPC$.\n",
2032                                 (unsigned int)info_level));
2033                         return NT_STATUS_ACCESS_DENIED;
2034                 }
2035         }
2036
2037         DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
2038
2039         smb_fname = (struct smb_filename) {
2040                 .base_name = discard_const_p(char, filename),
2041                 .flags = fname ? fname->flags : 0,
2042                 .twrp = fname ? fname->twrp : 0,
2043         };
2044
2045         if(info_level != SMB_FS_QUOTA_INFORMATION
2046            && SMB_VFS_STAT(conn, &smb_fname) != 0) {
2047                 DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
2048                 return map_nt_error_from_unix(errno);
2049         }
2050
2051         st = smb_fname.st;
2052
2053         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
2054                 return NT_STATUS_INVALID_PARAMETER;
2055         }
2056
2057         *ppdata = (char *)SMB_REALLOC(
2058                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2059         if (*ppdata == NULL) {
2060                 return NT_STATUS_NO_MEMORY;
2061         }
2062
2063         pdata = *ppdata;
2064         memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2065         end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2066
2067         *fixed_portion = 0;
2068
2069         switch (info_level) {
2070                 case SMB_INFO_ALLOCATION:
2071                 {
2072                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
2073                         data_len = 18;
2074                         df_ret = get_dfree_info(conn, &smb_fname, &bsize,
2075                                                 &dfree, &dsize);
2076                         if (df_ret == (uint64_t)-1) {
2077                                 return map_nt_error_from_unix(errno);
2078                         }
2079
2080                         block_size = lp_block_size(snum);
2081                         if (bsize < block_size) {
2082                                 uint64_t factor = block_size/bsize;
2083                                 bsize = block_size;
2084                                 dsize /= factor;
2085                                 dfree /= factor;
2086                         }
2087                         if (bsize > block_size) {
2088                                 uint64_t factor = bsize/block_size;
2089                                 bsize = block_size;
2090                                 dsize *= factor;
2091                                 dfree *= factor;
2092                         }
2093                         sectors_per_unit = bsize/bytes_per_sector;
2094
2095                         DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2096 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2097                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2098
2099                         /*
2100                          * For large drives, return max values and not modulo.
2101                          */
2102                         dsize = MIN(dsize, UINT32_MAX);
2103                         dfree = MIN(dfree, UINT32_MAX);
2104
2105                         SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
2106                         SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2107                         SIVAL(pdata,l1_cUnit,dsize);
2108                         SIVAL(pdata,l1_cUnitAvail,dfree);
2109                         SSVAL(pdata,l1_cbSector,bytes_per_sector);
2110                         break;
2111                 }
2112
2113                 case SMB_INFO_VOLUME:
2114                         /* Return volume name */
2115                         /*
2116                          * Add volume serial number - hash of a combination of
2117                          * the called hostname and the service name.
2118                          */
2119                         serial = generate_volume_serial_number(lp_sub, snum);
2120                         SIVAL(pdata,0,serial);
2121                         /*
2122                          * Win2k3 and previous mess this up by sending a name length
2123                          * one byte short. I believe only older clients (OS/2 Win9x) use
2124                          * this call so try fixing this by adding a terminating null to
2125                          * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2126                          */
2127                         status = srvstr_push(
2128                                 pdata, flags2,
2129                                 pdata+l2_vol_szVolLabel, vname,
2130                                 PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
2131                                 STR_NOALIGN|STR_TERMINATE, &len);
2132                         if (!NT_STATUS_IS_OK(status)) {
2133                                 return status;
2134                         }
2135                         SCVAL(pdata,l2_vol_cch,len);
2136                         data_len = l2_vol_szVolLabel + len;
2137                         DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %u, "
2138                                  "name = %s serial = 0x%04"PRIx32"\n",
2139                                  (unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
2140                                  (unsigned)len, vname, serial));
2141                         break;
2142
2143                 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2144                 case SMB_FS_ATTRIBUTE_INFORMATION:
2145
2146                         additional_flags = 0;
2147 #if defined(HAVE_SYS_QUOTAS)
2148                         additional_flags |= FILE_VOLUME_QUOTAS;
2149 #endif
2150
2151                         if(lp_nt_acl_support(SNUM(conn))) {
2152                                 additional_flags |= FILE_PERSISTENT_ACLS;
2153                         }
2154
2155                         /* Capabilities are filled in at connection time through STATVFS call */
2156                         additional_flags |= conn->fs_capabilities;
2157                         additional_flags |= lp_parm_int(conn->params->service,
2158                                                         "share", "fake_fscaps",
2159                                                         0);
2160
2161                         SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2162                                 FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
2163                                 additional_flags); /* FS ATTRIBUTES */
2164
2165                         SIVAL(pdata,4,255); /* Max filename component length */
2166                         /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2167                                 and will think we can't do long filenames */
2168                         status = srvstr_push(pdata, flags2, pdata+12, fstype,
2169                                           PTR_DIFF(end_data, pdata+12),
2170                                           STR_UNICODE, &len);
2171                         if (!NT_STATUS_IS_OK(status)) {
2172                                 return status;
2173                         }
2174                         SIVAL(pdata,8,len);
2175                         data_len = 12 + len;
2176                         if (max_data_bytes >= 16 && data_len > max_data_bytes) {
2177                                 /* the client only requested a portion of the
2178                                    file system name */
2179                                 data_len = max_data_bytes;
2180                                 status = STATUS_BUFFER_OVERFLOW;
2181                         }
2182                         *fixed_portion = 16;
2183                         break;
2184
2185                 case SMB_QUERY_FS_LABEL_INFO:
2186                 case SMB_FS_LABEL_INFORMATION:
2187                         status = srvstr_push(pdata, flags2, pdata+4, vname,
2188                                           PTR_DIFF(end_data, pdata+4), 0, &len);
2189                         if (!NT_STATUS_IS_OK(status)) {
2190                                 return status;
2191                         }
2192                         data_len = 4 + len;
2193                         SIVAL(pdata,0,len);
2194                         break;
2195
2196                 case SMB_QUERY_FS_VOLUME_INFO:
2197                 case SMB_FS_VOLUME_INFORMATION:
2198                         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER,
2199                                                     pdata, &st.st_ex_btime);
2200                         /*
2201                          * Add volume serial number - hash of a combination of
2202                          * the called hostname and the service name.
2203                          */
2204                         serial = generate_volume_serial_number(lp_sub, snum);
2205                         SIVAL(pdata,8,serial);
2206
2207                         /* Max label len is 32 characters. */
2208                         status = srvstr_push(pdata, flags2, pdata+18, vname,
2209                                           PTR_DIFF(end_data, pdata+18),
2210                                           STR_UNICODE, &len);
2211                         if (!NT_STATUS_IS_OK(status)) {
2212                                 return status;
2213                         }
2214                         SIVAL(pdata,12,len);
2215                         data_len = 18+len;
2216
2217                         DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO "
2218                                  "namelen = %d, vol=%s serv=%s "
2219                                  "serial=0x%04"PRIx32"\n",
2220                                  (int)strlen(vname),vname,
2221                                  lp_servicename(talloc_tos(), lp_sub, snum),
2222                                  serial));
2223                         if (max_data_bytes >= 24 && data_len > max_data_bytes) {
2224                                 /* the client only requested a portion of the
2225                                    volume label */
2226                                 data_len = max_data_bytes;
2227                                 status = STATUS_BUFFER_OVERFLOW;
2228                         }
2229                         *fixed_portion = 24;
2230                         break;
2231
2232                 case SMB_QUERY_FS_SIZE_INFO:
2233                 case SMB_FS_SIZE_INFORMATION:
2234                 {
2235                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
2236                         data_len = 24;
2237                         df_ret = get_dfree_info(conn, &smb_fname, &bsize,
2238                                                 &dfree, &dsize);
2239                         if (df_ret == (uint64_t)-1) {
2240                                 return map_nt_error_from_unix(errno);
2241                         }
2242                         block_size = lp_block_size(snum);
2243                         if (bsize < block_size) {
2244                                 uint64_t factor = block_size/bsize;
2245                                 bsize = block_size;
2246                                 dsize /= factor;
2247                                 dfree /= factor;
2248                         }
2249                         if (bsize > block_size) {
2250                                 uint64_t factor = bsize/block_size;
2251                                 bsize = block_size;
2252                                 dsize *= factor;
2253                                 dfree *= factor;
2254                         }
2255                         sectors_per_unit = bsize/bytes_per_sector;
2256                         DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2257 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2258                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2259                         SBIG_UINT(pdata,0,dsize);
2260                         SBIG_UINT(pdata,8,dfree);
2261                         SIVAL(pdata,16,sectors_per_unit);
2262                         SIVAL(pdata,20,bytes_per_sector);
2263                         *fixed_portion = 24;
2264                         break;
2265                 }
2266
2267                 case SMB_FS_FULL_SIZE_INFORMATION:
2268                 {
2269                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
2270                         data_len = 32;
2271                         df_ret = get_dfree_info(conn, &smb_fname, &bsize,
2272                                                 &dfree, &dsize);
2273                         if (df_ret == (uint64_t)-1) {
2274                                 return map_nt_error_from_unix(errno);
2275                         }
2276                         block_size = lp_block_size(snum);
2277                         if (bsize < block_size) {
2278                                 uint64_t factor = block_size/bsize;
2279                                 bsize = block_size;
2280                                 dsize /= factor;
2281                                 dfree /= factor;
2282                         }
2283                         if (bsize > block_size) {
2284                                 uint64_t factor = bsize/block_size;
2285                                 bsize = block_size;
2286                                 dsize *= factor;
2287                                 dfree *= factor;
2288                         }
2289                         sectors_per_unit = bsize/bytes_per_sector;
2290                         DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2291 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2292                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2293                         SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2294                         SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2295                         SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2296                         SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2297                         SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2298                         *fixed_portion = 32;
2299                         break;
2300                 }
2301
2302                 case SMB_QUERY_FS_DEVICE_INFO:
2303                 case SMB_FS_DEVICE_INFORMATION:
2304                 {
2305                         uint32_t characteristics = FILE_DEVICE_IS_MOUNTED;
2306
2307                         if (!CAN_WRITE(conn)) {
2308                                 characteristics |= FILE_READ_ONLY_DEVICE;
2309                         }
2310                         data_len = 8;
2311                         SIVAL(pdata,0,FILE_DEVICE_DISK); /* dev type */
2312                         SIVAL(pdata,4,characteristics);
2313                         *fixed_portion = 8;
2314                         break;
2315                 }
2316
2317 #ifdef HAVE_SYS_QUOTAS
2318                 case SMB_FS_QUOTA_INFORMATION:
2319                 /*
2320                  * what we have to send --metze:
2321                  *
2322                  * Unknown1:            24 NULL bytes
2323                  * Soft Quota Threshold: 8 bytes seems like uint64_t or so
2324                  * Hard Quota Limit:    8 bytes seems like uint64_t or so
2325                  * Quota Flags:         2 byte :
2326                  * Unknown3:            6 NULL bytes
2327                  *
2328                  * 48 bytes total
2329                  *
2330                  * details for Quota Flags:
2331                  *
2332                  * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2333                  * 0x0010 Log Warn:  log if the user exceeds his Soft Quota
2334                  * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2335                  * 0x0001 Enable Quotas: enable quota for this fs
2336                  *
2337                  */
2338                 {
2339                         /* we need to fake up a fsp here,
2340                          * because its not send in this call
2341                          */
2342                         files_struct tmpfsp;
2343                         SMB_NTQUOTA_STRUCT quotas;
2344
2345                         ZERO_STRUCT(tmpfsp);
2346                         ZERO_STRUCT(quotas);
2347
2348                         tmpfsp.conn = conn;
2349                         tmpfsp.fnum = FNUM_FIELD_INVALID;
2350
2351                         /* access check */
2352                         if (get_current_uid(conn) != 0) {
2353                                 DEBUG(0,("get_user_quota: access_denied "
2354                                          "service [%s] user [%s]\n",
2355                                          lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
2356                                          conn->session_info->unix_info->unix_name));
2357                                 return NT_STATUS_ACCESS_DENIED;
2358                         }
2359
2360                         status = vfs_get_ntquota(&tmpfsp, SMB_USER_FS_QUOTA_TYPE,
2361                                                  NULL, &quotas);
2362                         if (!NT_STATUS_IS_OK(status)) {
2363                                 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
2364                                 return status;
2365                         }
2366
2367                         data_len = 48;
2368
2369                         DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
2370                                   lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
2371
2372                         /* Unknown1 24 NULL bytes*/
2373                         SBIG_UINT(pdata,0,(uint64_t)0);
2374                         SBIG_UINT(pdata,8,(uint64_t)0);
2375                         SBIG_UINT(pdata,16,(uint64_t)0);
2376
2377                         /* Default Soft Quota 8 bytes */
2378                         SBIG_UINT(pdata,24,quotas.softlim);
2379
2380                         /* Default Hard Quota 8 bytes */
2381                         SBIG_UINT(pdata,32,quotas.hardlim);
2382
2383                         /* Quota flag 2 bytes */
2384                         SSVAL(pdata,40,quotas.qflags);
2385
2386                         /* Unknown3 6 NULL bytes */
2387                         SSVAL(pdata,42,0);
2388                         SIVAL(pdata,44,0);
2389
2390                         break;
2391                 }
2392 #endif /* HAVE_SYS_QUOTAS */
2393                 case SMB_FS_OBJECTID_INFORMATION:
2394                 {
2395                         unsigned char objid[16];
2396                         struct smb_extended_info extended_info;
2397                         memcpy(pdata,create_volume_objectid(conn, objid),16);
2398                         samba_extended_info_version (&extended_info);
2399                         SIVAL(pdata,16,extended_info.samba_magic);
2400                         SIVAL(pdata,20,extended_info.samba_version);
2401                         SIVAL(pdata,24,extended_info.samba_subversion);
2402                         SBIG_UINT(pdata,28,extended_info.samba_gitcommitdate);
2403                         memcpy(pdata+36,extended_info.samba_version_string,28);
2404                         data_len = 64;
2405                         break;
2406                 }
2407
2408                 case SMB_FS_SECTOR_SIZE_INFORMATION:
2409                 {
2410                         data_len = 28;
2411                         /*
2412                          * These values match a physical Windows Server 2012
2413                          * share backed by NTFS atop spinning rust.
2414                          */
2415                         DEBUG(5, ("SMB_FS_SECTOR_SIZE_INFORMATION:"));
2416                         /* logical_bytes_per_sector */
2417                         SIVAL(pdata, 0, bytes_per_sector);
2418                         /* phys_bytes_per_sector_atomic */
2419                         SIVAL(pdata, 4, bytes_per_sector);
2420                         /* phys_bytes_per_sector_perf */
2421                         SIVAL(pdata, 8, bytes_per_sector);
2422                         /* fs_effective_phys_bytes_per_sector_atomic */
2423                         SIVAL(pdata, 12, bytes_per_sector);
2424                         /* flags */
2425                         SIVAL(pdata, 16, SSINFO_FLAGS_ALIGNED_DEVICE
2426                                 | SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE);
2427                         /* byte_off_sector_align */
2428                         SIVAL(pdata, 20, 0);
2429                         /* byte_off_partition_align */
2430                         SIVAL(pdata, 24, 0);
2431                         *fixed_portion = 28;
2432                         break;
2433                 }
2434
2435
2436 #if defined(WITH_SMB1SERVER)
2437                 /*
2438                  * Query the version and capabilities of the CIFS UNIX extensions
2439                  * in use.
2440                  */
2441
2442                 case SMB_QUERY_CIFS_UNIX_INFO:
2443                 {
2444                         bool large_write = lp_min_receive_file_size() &&
2445                                         !smb1_srv_is_signing_active(xconn);
2446                         bool large_read = !smb1_srv_is_signing_active(xconn);
2447                         int encrypt_caps = 0;
2448
2449                         if (!lp_smb1_unix_extensions()) {
2450                                 return NT_STATUS_INVALID_LEVEL;
2451                         }
2452
2453                         switch (conn->encrypt_level) {
2454                         case SMB_SIGNING_OFF:
2455                                 encrypt_caps = 0;
2456                                 break;
2457                         case SMB_SIGNING_DESIRED:
2458                         case SMB_SIGNING_IF_REQUIRED:
2459                         case SMB_SIGNING_DEFAULT:
2460                                 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP;
2461                                 break;
2462                         case SMB_SIGNING_REQUIRED:
2463                                 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP|
2464                                                 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP;
2465                                 large_write = false;
2466                                 large_read = false;
2467                                 break;
2468                         }
2469
2470                         data_len = 12;
2471                         SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2472                         SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2473
2474                         /* We have POSIX ACLs, pathname, encryption,
2475                          * large read/write, and locking capability. */
2476
2477                         SBIG_UINT(pdata,4,((uint64_t)(
2478                                         CIFS_UNIX_POSIX_ACLS_CAP|
2479                                         CIFS_UNIX_POSIX_PATHNAMES_CAP|
2480                                         CIFS_UNIX_FCNTL_LOCKS_CAP|
2481                                         CIFS_UNIX_EXTATTR_CAP|
2482                                         CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP|
2483                                         encrypt_caps|
2484                                         (large_read ? CIFS_UNIX_LARGE_READ_CAP : 0) |
2485                                         (large_write ?
2486                                         CIFS_UNIX_LARGE_WRITE_CAP : 0))));
2487                         break;
2488                 }
2489 #endif
2490
2491                 case SMB_QUERY_POSIX_FS_INFO:
2492                 case SMB2_FS_POSIX_INFORMATION_INTERNAL:
2493                 {
2494                         int rc;
2495                         struct vfs_statvfs_struct svfs;
2496
2497                         if (!fsinfo_unix_valid_level(conn, fsp, info_level)) {
2498                                 return NT_STATUS_INVALID_LEVEL;
2499                         }
2500
2501                         rc = SMB_VFS_STATVFS(conn, &smb_fname, &svfs);
2502
2503                         if (!rc) {
2504                                 data_len = 56;
2505                                 SIVAL(pdata,0,svfs.OptimalTransferSize);
2506                                 SIVAL(pdata,4,svfs.BlockSize);
2507                                 SBIG_UINT(pdata,8,svfs.TotalBlocks);
2508                                 SBIG_UINT(pdata,16,svfs.BlocksAvail);
2509                                 SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
2510                                 SBIG_UINT(pdata,32,svfs.TotalFileNodes);
2511                                 SBIG_UINT(pdata,40,svfs.FreeFileNodes);
2512                                 SBIG_UINT(pdata,48,svfs.FsIdentifier);
2513                                 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO successful\n"));
2514 #ifdef EOPNOTSUPP
2515                         } else if (rc == EOPNOTSUPP) {
2516                                 return NT_STATUS_INVALID_LEVEL;
2517 #endif /* EOPNOTSUPP */
2518                         } else {
2519                                 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
2520                                 return NT_STATUS_DOS(ERRSRV, ERRerror);
2521                         }
2522                         break;
2523                 }
2524
2525                 case SMB_QUERY_POSIX_WHOAMI:
2526                 {
2527                         uint32_t flags = 0;
2528                         uint32_t sid_bytes;
2529                         uint32_t i;
2530
2531                         if (!lp_smb1_unix_extensions()) {
2532                                 return NT_STATUS_INVALID_LEVEL;
2533                         }
2534
2535                         if (max_data_bytes < 40) {
2536                                 return NT_STATUS_BUFFER_TOO_SMALL;
2537                         }
2538
2539                         if (security_session_user_level(conn->session_info, NULL) < SECURITY_USER) {
2540                                 flags |= SMB_WHOAMI_GUEST;
2541                         }
2542
2543                         /* NOTE: 8 bytes for UID/GID, irrespective of native
2544                          * platform size. This matches
2545                          * SMB_QUERY_FILE_UNIX_BASIC and friends.
2546                          */
2547                         data_len = 4 /* flags */
2548                             + 4 /* flag mask */
2549                             + 8 /* uid */
2550                             + 8 /* gid */
2551                             + 4 /* ngroups */
2552                             + 4 /* num_sids */
2553                             + 4 /* SID bytes */
2554                             + 4 /* pad/reserved */
2555                             + (conn->session_info->unix_token->ngroups * 8)
2556                                 /* groups list */
2557                             + (conn->session_info->security_token->num_sids *
2558                                     SID_MAX_SIZE)
2559                                 /* SID list */;
2560
2561                         SIVAL(pdata, 0, flags);
2562                         SIVAL(pdata, 4, SMB_WHOAMI_MASK);
2563                         SBIG_UINT(pdata, 8,
2564                                   (uint64_t)conn->session_info->unix_token->uid);
2565                         SBIG_UINT(pdata, 16,
2566                                   (uint64_t)conn->session_info->unix_token->gid);
2567
2568
2569                         if (data_len >= max_data_bytes) {
2570                                 /* Potential overflow, skip the GIDs and SIDs. */
2571
2572                                 SIVAL(pdata, 24, 0); /* num_groups */
2573                                 SIVAL(pdata, 28, 0); /* num_sids */
2574                                 SIVAL(pdata, 32, 0); /* num_sid_bytes */
2575                                 SIVAL(pdata, 36, 0); /* reserved */
2576
2577                                 data_len = 40;
2578                                 break;
2579                         }
2580
2581                         SIVAL(pdata, 24, conn->session_info->unix_token->ngroups);
2582                         SIVAL(pdata, 28, conn->session_info->security_token->num_sids);
2583
2584                         /* We walk the SID list twice, but this call is fairly
2585                          * infrequent, and I don't expect that it's performance
2586                          * sensitive -- jpeach
2587                          */
2588                         for (i = 0, sid_bytes = 0;
2589                              i < conn->session_info->security_token->num_sids; ++i) {
2590                                 sid_bytes += ndr_size_dom_sid(
2591                                         &conn->session_info->security_token->sids[i],
2592                                         0);
2593                         }
2594
2595                         /* SID list byte count */
2596                         SIVAL(pdata, 32, sid_bytes);
2597
2598                         /* 4 bytes pad/reserved - must be zero */
2599                         SIVAL(pdata, 36, 0);
2600                         data_len = 40;
2601
2602                         /* GID list */
2603                         for (i = 0; i < conn->session_info->unix_token->ngroups; ++i) {
2604                                 SBIG_UINT(pdata, data_len,
2605                                           (uint64_t)conn->session_info->unix_token->groups[i]);
2606                                 data_len += 8;
2607                         }
2608
2609                         /* SID list */
2610                         for (i = 0;
2611                             i < conn->session_info->security_token->num_sids; ++i) {
2612                                 int sid_len = ndr_size_dom_sid(
2613                                         &conn->session_info->security_token->sids[i],
2614                                         0);
2615
2616                                 sid_linearize((uint8_t *)(pdata + data_len),
2617                                               sid_len,
2618                                     &conn->session_info->security_token->sids[i]);
2619                                 data_len += sid_len;
2620                         }
2621
2622                         break;
2623                 }
2624
2625                 case SMB_MAC_QUERY_FS_INFO:
2626                         /*
2627                          * Thursby MAC extension... ONLY on NTFS filesystems
2628                          * once we do streams then we don't need this
2629                          */
2630                         if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2631                                 data_len = 88;
2632                                 SIVAL(pdata,84,0x100); /* Don't support mac... */
2633                                 break;
2634                         }
2635
2636                         FALL_THROUGH;
2637                 default:
2638                         return NT_STATUS_INVALID_LEVEL;
2639         }
2640
2641         *ret_data_len = data_len;
2642         return status;
2643 }
2644
2645 NTSTATUS smb_set_fsquota(connection_struct *conn,
2646                          struct smb_request *req,
2647                          files_struct *fsp,
2648                          const DATA_BLOB *qdata)
2649 {
2650         const struct loadparm_substitution *lp_sub =
2651                 loadparm_s3_global_substitution();
2652         NTSTATUS status;
2653         SMB_NTQUOTA_STRUCT quotas;
2654
2655         ZERO_STRUCT(quotas);
2656
2657         /* access check */
2658         if ((get_current_uid(conn) != 0) || !CAN_WRITE(conn)) {
2659                 DBG_NOTICE("access_denied service [%s] user [%s]\n",
2660                            lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
2661                            conn->session_info->unix_info->unix_name);
2662                 return NT_STATUS_ACCESS_DENIED;
2663         }
2664
2665         if (!check_fsp_ntquota_handle(conn, req,
2666                                       fsp)) {
2667                 DBG_WARNING("no valid QUOTA HANDLE\n");
2668                 return NT_STATUS_INVALID_HANDLE;
2669         }
2670
2671         /* note: normally there're 48 bytes,
2672          * but we didn't use the last 6 bytes for now
2673          * --metze
2674          */
2675         if (qdata->length < 42) {
2676                 DBG_ERR("requires total_data(%zu) >= 42 bytes!\n",
2677                         qdata->length);
2678                 return NT_STATUS_INVALID_PARAMETER;
2679         }
2680
2681         /* unknown_1 24 NULL bytes in pdata*/
2682
2683         /* the soft quotas 8 bytes (uint64_t)*/
2684         quotas.softlim = BVAL(qdata->data,24);
2685
2686         /* the hard quotas 8 bytes (uint64_t)*/
2687         quotas.hardlim = BVAL(qdata->data,32);
2688
2689         /* quota_flags 2 bytes **/
2690         quotas.qflags = SVAL(qdata->data,40);
2691
2692         /* unknown_2 6 NULL bytes follow*/
2693
2694         /* now set the quotas */
2695         if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
2696                 DBG_WARNING("vfs_set_ntquota() failed for service [%s]\n",
2697                             lp_servicename(talloc_tos(), lp_sub, SNUM(conn)));
2698                 status =  map_nt_error_from_unix(errno);
2699         } else {
2700                 status = NT_STATUS_OK;
2701         }
2702         return status;
2703 }
2704
2705 NTSTATUS smbd_do_setfsinfo(connection_struct *conn,
2706                                 struct smb_request *req,
2707                                 TALLOC_CTX *mem_ctx,
2708                                 uint16_t info_level,
2709                                 files_struct *fsp,
2710                                 const DATA_BLOB *pdata)
2711 {
2712         switch (info_level) {
2713                 case SMB_FS_QUOTA_INFORMATION:
2714                 {
2715                         return smb_set_fsquota(conn,
2716                                                 req,
2717                                                 fsp,
2718                                                 pdata);
2719                 }
2720
2721                 default:
2722                         break;
2723         }
2724         return NT_STATUS_INVALID_LEVEL;
2725 }
2726
2727 /****************************************************************************
2728  Store the FILE_UNIX_BASIC info.
2729 ****************************************************************************/
2730
2731 char *store_file_unix_basic(connection_struct *conn,
2732                             char *pdata,
2733                             files_struct *fsp,
2734                             const SMB_STRUCT_STAT *psbuf)
2735 {
2736         dev_t devno;
2737
2738         DBG_DEBUG("SMB_QUERY_FILE_UNIX_BASIC\n");
2739         DBG_NOTICE("st_mode=%o\n", (int)psbuf->st_ex_mode);
2740
2741         SOFF_T(pdata,0,get_file_size_stat(psbuf));             /* File size 64 Bit */
2742         pdata += 8;
2743
2744         SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
2745         pdata += 8;
2746
2747         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata, &psbuf->st_ex_ctime);       /* Change Time 64 Bit */
2748         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER ,pdata+8, &psbuf->st_ex_atime);     /* Last access time 64 Bit */
2749         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata+16, &psbuf->st_ex_mtime);    /* Last modification time 64 Bit */
2750         pdata += 24;
2751
2752         SIVAL(pdata,0,psbuf->st_ex_uid);               /* user id for the owner */
2753         SIVAL(pdata,4,0);
2754         pdata += 8;
2755
2756         SIVAL(pdata,0,psbuf->st_ex_gid);               /* group id of owner */
2757         SIVAL(pdata,4,0);
2758         pdata += 8;
2759
2760         SIVAL(pdata,0,unix_filetype(psbuf->st_ex_mode));
2761         pdata += 4;
2762
2763         if (S_ISBLK(psbuf->st_ex_mode) || S_ISCHR(psbuf->st_ex_mode)) {
2764                 devno = psbuf->st_ex_rdev;
2765         } else {
2766                 devno = psbuf->st_ex_dev;
2767         }
2768
2769         SIVAL(pdata,0,unix_dev_major(devno));   /* Major device number if type is device */
2770         SIVAL(pdata,4,0);
2771         pdata += 8;
2772
2773         SIVAL(pdata,0,unix_dev_minor(devno));   /* Minor device number if type is device */
2774         SIVAL(pdata,4,0);
2775         pdata += 8;
2776
2777         SINO_T_VAL(pdata, 0, psbuf->st_ex_ino);   /* inode number */
2778         pdata += 8;
2779
2780         SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode));     /* Standard UNIX file permissions */
2781         SIVAL(pdata,4,0);
2782         pdata += 8;
2783
2784         SIVAL(pdata,0,psbuf->st_ex_nlink);             /* number of hard links */
2785         SIVAL(pdata,4,0);
2786         pdata += 8;
2787
2788         return pdata;
2789 }
2790
2791 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
2792  * the chflags(2) (or equivalent) flags.
2793  *
2794  * XXX: this really should be behind the VFS interface. To do this, we would
2795  * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
2796  * Each VFS module could then implement its own mapping as appropriate for the
2797  * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
2798  */
2799 static const struct {unsigned stat_fflag; unsigned smb_fflag;}
2800         info2_flags_map[] =
2801 {
2802 #ifdef UF_NODUMP
2803     { UF_NODUMP, EXT_DO_NOT_BACKUP },
2804 #endif
2805
2806 #ifdef UF_IMMUTABLE
2807     { UF_IMMUTABLE, EXT_IMMUTABLE },
2808 #endif
2809
2810 #ifdef UF_APPEND
2811     { UF_APPEND, EXT_OPEN_APPEND_ONLY },
2812 #endif
2813
2814 #ifdef UF_HIDDEN
2815     { UF_HIDDEN, EXT_HIDDEN },
2816 #endif
2817
2818     /* Do not remove. We need to guarantee that this array has at least one
2819      * entry to build on HP-UX.
2820      */
2821     { 0, 0 }
2822
2823 };
2824
2825 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf,
2826                                 uint32_t *smb_fflags, uint32_t *smb_fmask)
2827 {
2828         size_t i;
2829
2830         for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
2831             *smb_fmask |= info2_flags_map[i].smb_fflag;
2832             if (psbuf->st_ex_flags & info2_flags_map[i].stat_fflag) {
2833                     *smb_fflags |= info2_flags_map[i].smb_fflag;
2834             }
2835         }
2836 }
2837
2838 bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
2839                              const uint32_t smb_fflags,
2840                              const uint32_t smb_fmask,
2841                              int *stat_fflags)
2842 {
2843         uint32_t max_fmask = 0;
2844         size_t i;
2845
2846         *stat_fflags = psbuf->st_ex_flags;
2847
2848         /* For each flags requested in smb_fmask, check the state of the
2849          * corresponding flag in smb_fflags and set or clear the matching
2850          * stat flag.
2851          */
2852
2853         for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
2854             max_fmask |= info2_flags_map[i].smb_fflag;
2855             if (smb_fmask & info2_flags_map[i].smb_fflag) {
2856                     if (smb_fflags & info2_flags_map[i].smb_fflag) {
2857                             *stat_fflags |= info2_flags_map[i].stat_fflag;
2858                     } else {
2859                             *stat_fflags &= ~info2_flags_map[i].stat_fflag;
2860                     }
2861             }
2862         }
2863
2864         /* If smb_fmask is asking to set any bits that are not supported by
2865          * our flag mappings, we should fail.
2866          */
2867         if ((smb_fmask & max_fmask) != smb_fmask) {
2868                 return False;
2869         }
2870
2871         return True;
2872 }
2873
2874
2875 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
2876  * of file flags and birth (create) time.
2877  */
2878 char *store_file_unix_basic_info2(connection_struct *conn,
2879                                   char *pdata,
2880                                   files_struct *fsp,
2881                                   const SMB_STRUCT_STAT *psbuf)
2882 {
2883         uint32_t file_flags = 0;
2884         uint32_t flags_mask = 0;
2885
2886         pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
2887
2888         /* Create (birth) time 64 bit */
2889         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER,pdata, &psbuf->st_ex_btime);
2890         pdata += 8;
2891
2892         map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
2893         SIVAL(pdata, 0, file_flags); /* flags */
2894         SIVAL(pdata, 4, flags_mask); /* mask */
2895         pdata += 8;
2896
2897         return pdata;
2898 }
2899
2900 static NTSTATUS marshall_stream_info(unsigned int num_streams,
2901                                      const struct stream_struct *streams,
2902                                      char *data,
2903                                      unsigned int max_data_bytes,
2904                                      unsigned int *data_size)
2905 {
2906         unsigned int i;
2907         unsigned int ofs = 0;
2908
2909         if (max_data_bytes < 32) {
2910                 return NT_STATUS_INFO_LENGTH_MISMATCH;
2911         }
2912
2913         for (i = 0; i < num_streams; i++) {
2914                 unsigned int next_offset;
2915                 size_t namelen;
2916                 smb_ucs2_t *namebuf;
2917
2918                 if (!push_ucs2_talloc(talloc_tos(), &namebuf,
2919                                       streams[i].name, &namelen) ||
2920                     namelen <= 2)
2921                 {
2922                         return NT_STATUS_INVALID_PARAMETER;
2923                 }
2924
2925                 /*
2926                  * name_buf is now null-terminated, we need to marshall as not
2927                  * terminated
2928                  */
2929
2930                 namelen -= 2;
2931
2932                 /*
2933                  * We cannot overflow ...
2934                  */
2935                 if ((ofs + 24 + namelen) > max_data_bytes) {
2936                         DEBUG(10, ("refusing to overflow reply at stream %u\n",
2937                                 i));
2938                         TALLOC_FREE(namebuf);
2939                         return STATUS_BUFFER_OVERFLOW;
2940                 }
2941
2942                 SIVAL(data, ofs+4, namelen);
2943                 SOFF_T(data, ofs+8, streams[i].size);
2944                 SOFF_T(data, ofs+16, streams[i].alloc_size);
2945                 memcpy(data+ofs+24, namebuf, namelen);
2946                 TALLOC_FREE(namebuf);
2947
2948                 next_offset = ofs + 24 + namelen;
2949
2950                 if (i == num_streams-1) {
2951                         SIVAL(data, ofs, 0);
2952                 }
2953                 else {
2954                         unsigned int align = ndr_align_size(next_offset, 8);
2955
2956                         if ((next_offset + align) > max_data_bytes) {
2957                                 DEBUG(10, ("refusing to overflow align "
2958                                         "reply at stream %u\n",
2959                                         i));
2960                                 TALLOC_FREE(namebuf);
2961                                 return STATUS_BUFFER_OVERFLOW;
2962                         }
2963
2964                         memset(data+next_offset, 0, align);
2965                         next_offset += align;
2966
2967                         SIVAL(data, ofs, next_offset - ofs);
2968                         ofs = next_offset;
2969                 }
2970
2971                 ofs = next_offset;
2972         }
2973
2974         DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes, ofs));
2975
2976         *data_size = ofs;
2977
2978         return NT_STATUS_OK;
2979 }
2980
2981 NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
2982                                TALLOC_CTX *mem_ctx,
2983                                struct smb_request *req,
2984                                uint16_t info_level,
2985                                files_struct *fsp,
2986                                struct smb_filename *smb_fname,
2987                                bool delete_pending,
2988                                struct timespec write_time_ts,
2989                                struct ea_list *ea_list,
2990                                uint16_t flags2,
2991                                unsigned int max_data_bytes,
2992                                size_t *fixed_portion,
2993                                char **ppdata,
2994                                unsigned int *pdata_size)
2995 {
2996         char *pdata = *ppdata;
2997         char *dstart, *dend;
2998         unsigned int data_size;
2999         struct timespec create_time_ts, mtime_ts, atime_ts, ctime_ts;
3000         SMB_STRUCT_STAT *psbuf = NULL;
3001         SMB_STRUCT_STAT *base_sp = NULL;
3002         char *p;
3003         char *base_name;
3004         char *dos_fname;
3005         int mode;
3006         int nlink;
3007         NTSTATUS status;
3008         uint64_t file_size = 0;
3009         uint64_t pos = 0;
3010         uint64_t allocation_size = 0;
3011         uint64_t file_id = 0;
3012         uint32_t access_mask = 0;
3013         size_t len = 0;
3014
3015         if (INFO_LEVEL_IS_UNIX(info_level)) {
3016                 bool ok = false;
3017
3018                 if (lp_smb1_unix_extensions() && req->posix_pathnames) {
3019                         DBG_DEBUG("SMB1 unix extensions activated\n");
3020                         ok = true;
3021                 }
3022
3023                 if (conn->sconn->using_smb2 &&
3024                     (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN))
3025                 {
3026                         DBG_DEBUG("SMB2 posix open\n");
3027                         ok = true;
3028                 }
3029
3030                 if (!ok) {
3031                         return NT_STATUS_INVALID_LEVEL;
3032                 }
3033         }
3034
3035         DBG_INFO("%s (%s) level=%d max_data=%u\n",
3036                  smb_fname_str_dbg(smb_fname),
3037                  fsp_fnum_dbg(fsp),
3038                  info_level, max_data_bytes);
3039
3040         /*
3041          * In case of querying a symlink in POSIX context,
3042          * fsp will be NULL. fdos_mode() deals with it.
3043          */
3044         if (fsp != NULL) {
3045                 smb_fname = fsp->fsp_name;
3046         }
3047         mode = fdos_mode(fsp);
3048         psbuf = &smb_fname->st;
3049
3050         if (fsp != NULL) {
3051                 base_sp = fsp->base_fsp ?
3052                         &fsp->base_fsp->fsp_name->st :
3053                         &fsp->fsp_name->st;
3054         } else {
3055                 base_sp = &smb_fname->st;
3056         }
3057
3058         nlink = psbuf->st_ex_nlink;
3059
3060         if (nlink && (mode&FILE_ATTRIBUTE_DIRECTORY)) {
3061                 nlink = 1;
3062         }
3063
3064         if ((nlink > 0) && delete_pending) {
3065                 nlink -= 1;
3066         }
3067
3068         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
3069                 return NT_STATUS_INVALID_PARAMETER;
3070         }
3071
3072         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
3073         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
3074         if (*ppdata == NULL) {
3075                 return NT_STATUS_NO_MEMORY;
3076         }
3077         pdata = *ppdata;
3078         dstart = pdata;
3079         dend = dstart + data_size - 1;
3080
3081         if (!is_omit_timespec(&write_time_ts) &&
3082             !INFO_LEVEL_IS_UNIX(info_level))
3083         {
3084                 update_stat_ex_mtime(psbuf, write_time_ts);
3085         }
3086
3087         create_time_ts = get_create_timespec(conn, fsp, smb_fname);
3088         mtime_ts = psbuf->st_ex_mtime;
3089         atime_ts = psbuf->st_ex_atime;
3090         ctime_ts = get_change_timespec(conn, fsp, smb_fname);
3091
3092         if (lp_dos_filetime_resolution(SNUM(conn))) {
3093                 dos_filetime_timespec(&create_time_ts);
3094                 dos_filetime_timespec(&mtime_ts);
3095                 dos_filetime_timespec(&atime_ts);
3096                 dos_filetime_timespec(&ctime_ts);
3097         }
3098
3099         p = strrchr_m(smb_fname->base_name,'/');
3100         if (!p)
3101                 base_name = smb_fname->base_name;
3102         else
3103                 base_name = p+1;
3104
3105         /* NT expects the name to be in an exact form of the *full*
3106            filename. See the trans2 torture test */
3107         if (ISDOT(base_name)) {
3108                 dos_fname = talloc_strdup(mem_ctx, "\\");
3109                 if (!dos_fname) {
3110                         return NT_STATUS_NO_MEMORY;
3111                 }
3112         } else {
3113                 dos_fname = talloc_asprintf(mem_ctx,
3114                                 "\\%s",
3115                                 smb_fname->base_name);
3116                 if (!dos_fname) {
3117                         return NT_STATUS_NO_MEMORY;
3118                 }
3119                 if (is_named_stream(smb_fname)) {
3120                         dos_fname = talloc_asprintf(dos_fname, "%s",
3121                                                     smb_fname->stream_name);
3122                         if (!dos_fname) {
3123                                 return NT_STATUS_NO_MEMORY;
3124                         }
3125                 }
3126
3127                 string_replace(dos_fname, '/', '\\');
3128         }
3129
3130         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, psbuf);
3131
3132         if (fsp == NULL || !fsp->fsp_flags.is_fsa) {
3133                 /* Do we have this path open ? */
3134                 struct file_id fileid = vfs_file_id_from_sbuf(conn, psbuf);
3135                 files_struct *fsp1 = file_find_di_first(
3136                         conn->sconn, fileid, true);
3137                 if (fsp1 && fsp1->initial_allocation_size) {
3138                         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, psbuf);
3139                 }
3140         }
3141
3142         if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
3143                 file_size = get_file_size_stat(psbuf);
3144         }
3145
3146         if (fsp) {
3147                 pos = fh_get_position_information(fsp->fh);
3148         }
3149
3150         if (fsp) {
3151                 access_mask = fsp->access_mask;
3152         } else {
3153                 /* GENERIC_EXECUTE mapping from Windows */
3154                 access_mask = 0x12019F;
3155         }
3156
3157         /* This should be an index number - looks like
3158            dev/ino to me :-)
3159
3160            I think this causes us to fail the IFSKIT
3161            BasicFileInformationTest. -tpot */
3162         file_id = SMB_VFS_FS_FILE_ID(conn, base_sp);
3163
3164         *fixed_portion = 0;
3165
3166         switch (info_level) {
3167                 case SMB_INFO_STANDARD:
3168                         DBG_DEBUG("SMB_INFO_STANDARD\n");
3169                         data_size = 22;
3170                         srv_put_dos_date2_ts(pdata,
3171                                              l1_fdateCreation,
3172                                              create_time_ts);
3173                         srv_put_dos_date2_ts(pdata,
3174                                              l1_fdateLastAccess,
3175                                              atime_ts);
3176                         srv_put_dos_date2_ts(pdata,
3177                                              l1_fdateLastWrite,
3178                                              mtime_ts); /* write time */
3179                         SIVAL(pdata,l1_cbFile,(uint32_t)file_size);
3180                         SIVAL(pdata,l1_cbFileAlloc,(uint32_t)allocation_size);
3181                         SSVAL(pdata,l1_attrFile,mode);
3182                         break;
3183
3184                 case SMB_INFO_QUERY_EA_SIZE:
3185                 {
3186                         unsigned int ea_size =
3187                             estimate_ea_size(smb_fname->fsp);
3188                         DBG_DEBUG("SMB_INFO_QUERY_EA_SIZE\n");
3189                         data_size = 26;
3190                         srv_put_dos_date2_ts(pdata, 0, create_time_ts);
3191                         srv_put_dos_date2_ts(pdata, 4, atime_ts);
3192                         srv_put_dos_date2_ts(pdata,
3193                                              8,
3194                                              mtime_ts); /* write time */
3195                         SIVAL(pdata,12,(uint32_t)file_size);
3196                         SIVAL(pdata,16,(uint32_t)allocation_size);
3197                         SSVAL(pdata,20,mode);
3198                         SIVAL(pdata,22,ea_size);
3199                         break;
3200                 }
3201
3202                 case SMB_INFO_IS_NAME_VALID:
3203                         DBG_DEBUG("SMB_INFO_IS_NAME_VALID\n");
3204                         if (fsp) {
3205                                 /* os/2 needs this ? really ?*/
3206                                 return NT_STATUS_DOS(ERRDOS, ERRbadfunc);
3207                         }
3208                         /* This is only reached for qpathinfo */
3209                         data_size = 0;
3210                         break;
3211
3212                 case SMB_INFO_QUERY_EAS_FROM_LIST:
3213                 {
3214                         size_t total_ea_len = 0;
3215                         struct ea_list *ea_file_list = NULL;
3216                         DBG_DEBUG("SMB_INFO_QUERY_EAS_FROM_LIST\n");
3217
3218                         status =
3219                             get_ea_list_from_fsp(mem_ctx,
3220                                                   smb_fname->fsp,
3221                                                   &total_ea_len, &ea_file_list);
3222                         if (!NT_STATUS_IS_OK(status)) {
3223                                 return status;
3224                         }
3225
3226                         ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
3227
3228                         if (!ea_list || (total_ea_len > data_size)) {
3229                                 data_size = 4;
3230                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
3231                                 break;
3232                         }
3233
3234                         data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
3235                         break;
3236                 }
3237
3238                 case SMB_INFO_QUERY_ALL_EAS:
3239                 {
3240                         /* We have data_size bytes to put EA's into. */
3241                         size_t total_ea_len = 0;
3242                         DBG_DEBUG(" SMB_INFO_QUERY_ALL_EAS\n");
3243
3244                         status = get_ea_list_from_fsp(mem_ctx,
3245                                                         smb_fname->fsp,
3246                                                         &total_ea_len, &ea_list);
3247                         if (!NT_STATUS_IS_OK(status)) {
3248                                 return status;
3249                         }
3250
3251                         if (!ea_list || (total_ea_len > data_size)) {
3252                                 data_size = 4;
3253                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
3254                                 break;
3255                         }
3256
3257                         data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
3258                         break;
3259                 }
3260
3261                 case SMB2_FILE_FULL_EA_INFORMATION:
3262                 {
3263                         /* We have data_size bytes to put EA's into. */
3264                         size_t total_ea_len = 0;
3265                         struct ea_list *ea_file_list = NULL;
3266
3267                         DBG_DEBUG("SMB2_INFO_QUERY_ALL_EAS\n");
3268
3269                         /*TODO: add filtering and index handling */
3270
3271                         status  =
3272                                 get_ea_list_from_fsp(mem_ctx,
3273                                                   smb_fname->fsp,
3274                                                   &total_ea_len, &ea_file_list);
3275                         if (!NT_STATUS_IS_OK(status)) {
3276                                 return status;
3277                         }
3278                         if (!ea_file_list) {
3279                                 return NT_STATUS_NO_EAS_ON_FILE;
3280                         }
3281
3282                         status = fill_ea_chained_buffer(mem_ctx,
3283                                                         pdata,
3284                                                         data_size,
3285                                                         &data_size,
3286                                                         conn, ea_file_list);
3287                         if (!NT_STATUS_IS_OK(status)) {
3288                                 return status;
3289                         }
3290                         break;
3291                 }
3292
3293                 case SMB_FILE_BASIC_INFORMATION:
3294                 case SMB_QUERY_FILE_BASIC_INFO:
3295
3296                         if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
3297                                 DBG_DEBUG("SMB_QUERY_FILE_BASIC_INFO\n");
3298                                 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
3299                         } else {
3300                                 DBG_DEBUG("SMB_FILE_BASIC_INFORMATION\n");
3301                                 data_size = 40;
3302                                 SIVAL(pdata,36,0);
3303                         }
3304                         put_long_date_full_timespec(conn->ts_res,pdata,&create_time_ts);
3305                         put_long_date_full_timespec(conn->ts_res,pdata+8,&atime_ts);
3306                         put_long_date_full_timespec(conn->ts_res,pdata+16,&mtime_ts); /* write time */
3307                         put_long_date_full_timespec(conn->ts_res,pdata+24,&ctime_ts); /* change time */
3308                         SIVAL(pdata,32,mode);
3309
3310                         DBG_INFO("SMB_QFBI - create: %s access: %s "
3311                                  "write: %s change: %s mode: %x\n",
3312                                  ctime(&create_time_ts.tv_sec),
3313                                  ctime(&atime_ts.tv_sec),
3314                                  ctime(&mtime_ts.tv_sec),
3315                                  ctime(&ctime_ts.tv_sec),
3316                                  mode);
3317                         *fixed_portion = data_size;
3318                         break;
3319
3320                 case SMB_FILE_STANDARD_INFORMATION:
3321                 case SMB_QUERY_FILE_STANDARD_INFO:
3322
3323                         DBG_DEBUG("SMB_FILE_STANDARD_INFORMATION\n");
3324                         data_size = 24;
3325                         SOFF_T(pdata,0,allocation_size);
3326                         SOFF_T(pdata,8,file_size);
3327                         SIVAL(pdata,16,nlink);
3328                         SCVAL(pdata,20,delete_pending?1:0);
3329                         SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
3330                         SSVAL(pdata,22,0); /* Padding. */
3331                         *fixed_portion = 24;
3332                         break;
3333
3334                 case SMB_FILE_EA_INFORMATION:
3335                 case SMB_QUERY_FILE_EA_INFO:
3336                 {
3337                         unsigned int ea_size =
3338                             estimate_ea_size(smb_fname->fsp);
3339                         DBG_DEBUG("SMB_FILE_EA_INFORMATION\n");
3340                         data_size = 4;
3341                         *fixed_portion = 4;
3342                         SIVAL(pdata,0,ea_size);
3343                         break;
3344                 }
3345
3346                 /* Get the 8.3 name - used if NT SMB was negotiated. */
3347                 case SMB_QUERY_FILE_ALT_NAME_INFO:
3348                 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
3349                 {
3350                         char mangled_name[13];
3351                         DBG_DEBUG("SMB_FILE_ALTERNATE_NAME_INFORMATION\n");
3352                         if (!name_to_8_3(base_name,mangled_name,
3353                                                 True,conn->params)) {
3354                                 return NT_STATUS_NO_MEMORY;
3355                         }
3356                         status = srvstr_push(dstart, flags2,
3357                                           pdata+4, mangled_name,
3358                                           PTR_DIFF(dend, pdata+4),
3359                                           STR_UNICODE, &len);
3360                         if (!NT_STATUS_IS_OK(status)) {
3361                                 return status;
3362                         }
3363                         data_size = 4 + len;
3364                         SIVAL(pdata,0,len);
3365                         *fixed_portion = 8;
3366                         break;
3367                 }
3368
3369                 case SMB_QUERY_FILE_NAME_INFO:
3370                 {
3371                         /*
3372                           this must be *exactly* right for ACLs on mapped drives to work
3373                          */
3374                         status = srvstr_push(dstart, flags2,
3375                                           pdata+4, dos_fname,
3376                                           PTR_DIFF(dend, pdata+4),
3377                                           STR_UNICODE, &len);
3378                         if (!NT_STATUS_IS_OK(status)) {
3379                                 return status;
3380                         }
3381                         DBG_DEBUG("SMB_QUERY_FILE_NAME_INFO\n");
3382                         data_size = 4 + len;
3383                         SIVAL(pdata,0,len);
3384                         break;
3385                 }
3386
3387                 case SMB_FILE_NORMALIZED_NAME_INFORMATION:
3388                 {
3389                         char *nfname = NULL;
3390
3391                         if (fsp == NULL || !fsp->conn->sconn->using_smb2) {
3392                                 return NT_STATUS_INVALID_LEVEL;
3393                         }
3394
3395                         nfname = talloc_strdup(mem_ctx, smb_fname->base_name);
3396                         if (nfname == NULL) {
3397                                 return NT_STATUS_NO_MEMORY;
3398                         }
3399
3400                         if (ISDOT(nfname)) {
3401                                 nfname[0] = '\0';
3402                         }
3403                         string_replace(nfname, '/', '\\');
3404
3405                         if (fsp_is_alternate_stream(fsp)) {
3406                                 const char *s = smb_fname->stream_name;
3407                                 const char *e = NULL;
3408                                 size_t n;
3409
3410                                 SMB_ASSERT(s[0] != '\0');
3411
3412                                 /*
3413                                  * smb_fname->stream_name is in form
3414                                  * of ':StrEam:$DATA', but we should only
3415                                  * append ':StrEam' here.
3416                                  */
3417
3418                                 e = strchr(&s[1], ':');
3419                                 if (e == NULL) {
3420                                         n = strlen(s);
3421                                 } else {
3422                                         n = PTR_DIFF(e, s);
3423                                 }
3424                                 nfname = talloc_strndup_append(nfname, s, n);
3425                                 if (nfname == NULL) {
3426                                         return NT_STATUS_NO_MEMORY;
3427                                 }
3428                         }
3429
3430                         status = srvstr_push(dstart, flags2,
3431                                           pdata+4, nfname,
3432                                           PTR_DIFF(dend, pdata+4),
3433                                           STR_UNICODE, &len);
3434                         if (!NT_STATUS_IS_OK(status)) {
3435                                 return status;
3436                         }
3437                         DBG_DEBUG("SMB_FILE_NORMALIZED_NAME_INFORMATION\n");
3438                         data_size = 4 + len;
3439                         SIVAL(pdata,0,len);
3440                         *fixed_portion = 8;
3441                         break;
3442                 }
3443
3444                 case SMB_FILE_ALLOCATION_INFORMATION:
3445                 case SMB_QUERY_FILE_ALLOCATION_INFO:
3446                         DBG_DEBUG("SMB_FILE_ALLOCATION_INFORMATION\n");
3447                         data_size = 8;
3448                         SOFF_T(pdata,0,allocation_size);
3449                         break;
3450
3451                 case SMB_FILE_END_OF_FILE_INFORMATION:
3452                 case SMB_QUERY_FILE_END_OF_FILEINFO:
3453                         DBG_DEBUG("SMB_FILE_END_OF_FILE_INFORMATION\n");
3454                         data_size = 8;
3455                         SOFF_T(pdata,0,file_size);
3456                         break;
3457
3458                 case SMB_QUERY_FILE_ALL_INFO:
3459                 case SMB_FILE_ALL_INFORMATION:
3460                 {
3461                         unsigned int ea_size =
3462                             estimate_ea_size(smb_fname->fsp);
3463                         DBG_DEBUG("SMB_FILE_ALL_INFORMATION\n");
3464                         put_long_date_full_timespec(conn->ts_res,pdata,&create_time_ts);
3465                         put_long_date_full_timespec(conn->ts_res,pdata+8,&atime_ts);
3466                         put_long_date_full_timespec(conn->ts_res,pdata+16,&mtime_ts); /* write time */
3467                         put_long_date_full_timespec(conn->ts_res,pdata+24,&ctime_ts); /* change time */
3468                         SIVAL(pdata,32,mode);
3469                         SIVAL(pdata,36,0); /* padding. */
3470                         pdata += 40;
3471                         SOFF_T(pdata,0,allocation_size);
3472                         SOFF_T(pdata,8,file_size);
3473                         SIVAL(pdata,16,nlink);
3474                         SCVAL(pdata,20,delete_pending);
3475                         SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
3476                         SSVAL(pdata,22,0);
3477                         pdata += 24;
3478                         SIVAL(pdata,0,ea_size);
3479                         pdata += 4; /* EA info */
3480                         status = srvstr_push(dstart, flags2,
3481                                           pdata+4, dos_fname,
3482                                           PTR_DIFF(dend, pdata+4),
3483                                           STR_UNICODE, &len);
3484                         if (!NT_STATUS_IS_OK(status)) {
3485                                 return status;
3486                         }
3487                         SIVAL(pdata,0,len);
3488                         pdata += 4 + len;
3489                         data_size = PTR_DIFF(pdata,(*ppdata));
3490                         *fixed_portion = 10;
3491                         break;
3492                 }
3493
3494                 case SMB2_FILE_ALL_INFORMATION:
3495                 {
3496                         unsigned int ea_size =
3497                             estimate_ea_size(smb_fname->fsp);
3498                         DBG_DEBUG("SMB2_FILE_ALL_INFORMATION\n");
3499                         put_long_date_full_timespec(conn->ts_res,pdata+0x00,&create_time_ts);
3500                         put_long_date_full_timespec(conn->ts_res,pdata+0x08,&atime_ts);
3501                         put_long_date_full_timespec(conn->ts_res,pdata+0x10,&mtime_ts); /* write time */
3502                         put_long_date_full_timespec(conn->ts_res,pdata+0x18,&ctime_ts); /* change time */
3503                         SIVAL(pdata,    0x20, mode);
3504                         SIVAL(pdata,    0x24, 0); /* padding. */
3505                         SBVAL(pdata,    0x28, allocation_size);
3506                         SBVAL(pdata,    0x30, file_size);
3507                         SIVAL(pdata,    0x38, nlink);
3508                         SCVAL(pdata,    0x3C, delete_pending);
3509                         SCVAL(pdata,    0x3D, (mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
3510                         SSVAL(pdata,    0x3E, 0); /* padding */
3511                         SBVAL(pdata,    0x40, file_id);
3512                         SIVAL(pdata,    0x48, ea_size);
3513                         SIVAL(pdata,    0x4C, access_mask);
3514                         SBVAL(pdata,    0x50, pos);
3515                         SIVAL(pdata,    0x58, mode); /*TODO: mode != mode fix this!!! */
3516                         SIVAL(pdata,    0x5C, 0); /* No alignment needed. */
3517
3518                         pdata += 0x60;
3519
3520                         status = srvstr_push(dstart, flags2,
3521                                           pdata+4, dos_fname,
3522                                           PTR_DIFF(dend, pdata+4),
3523                                           STR_UNICODE, &len);
3524                         if (!NT_STATUS_IS_OK(status)) {
3525                                 return status;
3526                         }
3527                         SIVAL(pdata,0,len);
3528                         pdata += 4 + len;
3529                         data_size = PTR_DIFF(pdata,(*ppdata));
3530                         *fixed_portion = 104;
3531                         break;
3532                 }
3533                 case SMB_FILE_INTERNAL_INFORMATION:
3534
3535                         DBG_DEBUG("SMB_FILE_INTERNAL_INFORMATION\n");
3536                         SBVAL(pdata, 0, file_id);
3537                         data_size = 8;
3538                         *fixed_portion = 8;
3539                         break;
3540
3541                 case SMB_FILE_ACCESS_INFORMATION:
3542                         DBG_DEBUG("SMB_FILE_ACCESS_INFORMATION\n");
3543                         SIVAL(pdata, 0, access_mask);
3544                         data_size = 4;
3545                         *fixed_portion = 4;
3546                         break;
3547
3548                 case SMB_FILE_NAME_INFORMATION:
3549                         /* Pathname with leading '\'. */
3550                         {
3551                                 size_t byte_len;
3552                                 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
3553                                 DBG_DEBUG("SMB_FILE_NAME_INFORMATION\n");
3554                                 SIVAL(pdata,0,byte_len);
3555                                 data_size = 4 + byte_len;
3556                                 break;
3557                         }
3558
3559                 case SMB_FILE_DISPOSITION_INFORMATION:
3560                         DBG_DEBUG("SMB_FILE_DISPOSITION_INFORMATION\n");
3561                         data_size = 1;
3562                         SCVAL(pdata,0,delete_pending);
3563                         *fixed_portion = 1;
3564                         break;
3565
3566                 case SMB_FILE_POSITION_INFORMATION:
3567                         DBG_DEBUG("SMB_FILE_POSITION_INFORMATION\n");
3568                         data_size = 8;
3569                         SOFF_T(pdata,0,pos);
3570                         *fixed_portion = 8;
3571                         break;
3572
3573                 case SMB_FILE_MODE_INFORMATION:
3574                         DBG_DEBUG("SMB_FILE_MODE_INFORMATION\n");
3575                         SIVAL(pdata,0,mode);
3576                         data_size = 4;
3577                         *fixed_portion = 4;
3578                         break;
3579
3580                 case SMB_FILE_ALIGNMENT_INFORMATION:
3581                         DBG_DEBUG("SMB_FILE_ALIGNMENT_INFORMATION\n");
3582                         SIVAL(pdata,0,0); /* No alignment needed. */
3583                         data_size = 4;
3584                         *fixed_portion = 4;
3585                         break;
3586
3587                 /*
3588                  * NT4 server just returns "invalid query" to this - if we try
3589                  * to answer it then NTws gets a BSOD! (tridge).  W2K seems to
3590                  * want this. JRA.
3591                  */
3592                 /* The first statement above is false - verified using Thursby
3593                  * client against NT4 -- gcolley.
3594                  */
3595                 case SMB_QUERY_FILE_STREAM_INFO:
3596                 case SMB_FILE_STREAM_INFORMATION: {
3597                         unsigned int num_streams = 0;
3598                         struct stream_struct *streams = NULL;
3599
3600                         DBG_DEBUG("SMB_FILE_STREAM_INFORMATION\n");
3601
3602                         if (is_ntfs_stream_smb_fname(smb_fname)) {
3603                                 return NT_STATUS_INVALID_PARAMETER;
3604                         }
3605
3606                         status = vfs_fstreaminfo(fsp,
3607                                                 mem_ctx,
3608                                                 &num_streams,
3609                                                 &streams);
3610
3611                         if (!NT_STATUS_IS_OK(status)) {
3612                                 DBG_DEBUG("could not get stream info: %s\n",
3613                                           nt_errstr(status));
3614                                 return status;
3615                         }
3616
3617                         status = marshall_stream_info(num_streams, streams,
3618                                                       pdata, max_data_bytes,
3619                                                       &data_size);
3620
3621                         if (!NT_STATUS_IS_OK(status)) {
3622                                 DBG_DEBUG("marshall_stream_info failed: %s\n",
3623                                           nt_errstr(status));
3624                                 TALLOC_FREE(streams);
3625                                 return status;
3626                         }
3627
3628                         TALLOC_FREE(streams);
3629
3630                         *fixed_portion = 32;
3631
3632                         break;
3633                 }
3634                 case SMB_QUERY_COMPRESSION_INFO:
3635                 case SMB_FILE_COMPRESSION_INFORMATION:
3636                         DBG_DEBUG("SMB_FILE_COMPRESSION_INFORMATION\n");
3637                         SOFF_T(pdata,0,file_size);
3638                         SIVAL(pdata,8,0); /* ??? */
3639                         SIVAL(pdata,12,0); /* ??? */
3640                         data_size = 16;
3641                         *fixed_portion = 16;
3642                         break;
3643
3644                 case SMB_FILE_NETWORK_OPEN_INFORMATION:
3645                         DBG_DEBUG("SMB_FILE_NETWORK_OPEN_INFORMATION\n");
3646                         put_long_date_full_timespec(conn->ts_res,pdata,&create_time_ts);
3647                         put_long_date_full_timespec(conn->ts_res,pdata+8,&atime_ts);
3648                         put_long_date_full_timespec(conn->ts_res,pdata+16,&mtime_ts); /* write time */
3649                         put_long_date_full_timespec(conn->ts_res,pdata+24,&ctime_ts); /* change time */
3650                         SOFF_T(pdata,32,allocation_size);
3651                         SOFF_T(pdata,40,file_size);
3652                         SIVAL(pdata,48,mode);
3653                         SIVAL(pdata,52,0); /* ??? */
3654                         data_size = 56;
3655                         *fixed_portion = 56;
3656                         break;
3657
3658                 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
3659                         DBG_DEBUG(" SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n");
3660                         SIVAL(pdata,0,mode);
3661                         SIVAL(pdata,4,0);
3662                         data_size = 8;
3663                         *fixed_portion = 8;
3664                         break;
3665
3666                 /*
3667                  * SMB2 UNIX Extensions.
3668                  */
3669                 case SMB2_FILE_POSIX_INFORMATION_INTERNAL:
3670                 {
3671                         struct smb3_file_posix_information info = {};
3672                         uint8_t buf[sizeof(info)];
3673                         struct ndr_push ndr = {
3674                                 .data = buf,
3675                                 .alloc_size = sizeof(buf),
3676                                 .fixed_buf_size = true,
3677                         };
3678                         enum ndr_err_code ndr_err;
3679
3680                         if (!(conn->sconn->using_smb2)) {
3681                                 return NT_STATUS_INVALID_LEVEL;
3682                         }
3683                         if (fsp == NULL) {
3684                                 return NT_STATUS_INVALID_HANDLE;
3685                         }
3686                         if (!(fsp->posix_flags & FSP_POSIX_FLAGS_OPEN)) {
3687                                 return NT_STATUS_INVALID_LEVEL;
3688                         }
3689
3690                         smb3_file_posix_information_init(
3691                                 conn, &smb_fname->st, 0, mode, &info);
3692
3693                         ndr_err = ndr_push_smb3_file_posix_information(
3694                                 &ndr, NDR_SCALARS|NDR_BUFFERS, &info);
3695                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3696                                 return NT_STATUS_INSUFFICIENT_RESOURCES;
3697                         }
3698
3699                         memcpy(pdata, buf, ndr.offset);
3700                         data_size = ndr.offset;
3701                         break;
3702                 }
3703
3704                 default:
3705                         return NT_STATUS_INVALID_LEVEL;
3706         }
3707
3708         *pdata_size = data_size;
3709         return NT_STATUS_OK;
3710 }
3711
3712 /****************************************************************************
3713  Set a hard link (called by UNIX extensions and by NT rename with HARD link
3714  code.
3715 ****************************************************************************/
3716
3717 NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
3718                 connection_struct *conn,
3719                 struct smb_request *req,
3720                 bool overwrite_if_exists,
3721                 const struct smb_filename *smb_fname_old,
3722                 struct smb_filename *smb_fname_new)
3723 {
3724         NTSTATUS status = NT_STATUS_OK;
3725         int ret;
3726         bool ok;
3727         struct smb_filename *parent_fname_old = NULL;
3728         struct smb_filename *base_name_old = NULL;
3729         struct smb_filename *parent_fname_new = NULL;
3730         struct smb_filename *base_name_new = NULL;
3731
3732         /* source must already exist. */
3733         if (!VALID_STAT(smb_fname_old->st)) {
3734                 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3735                 goto out;
3736         }
3737
3738         /* No links from a directory. */
3739         if (S_ISDIR(smb_fname_old->st.st_ex_mode)) {
3740                 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3741                 goto out;
3742         }
3743
3744         /* Setting a hardlink to/from a stream isn't currently supported. */
3745         ok = is_ntfs_stream_smb_fname(smb_fname_old);
3746         if (ok) {
3747                 DBG_DEBUG("Old name has streams\n");
3748                 status = NT_STATUS_INVALID_PARAMETER;
3749                 goto out;
3750         }
3751         ok = is_ntfs_stream_smb_fname(smb_fname_new);
3752         if (ok) {
3753                 DBG_DEBUG("New name has streams\n");
3754                 status = NT_STATUS_INVALID_PARAMETER;
3755                 goto out;
3756         }
3757
3758         if (smb_fname_old->twrp != 0) {
3759                 status = NT_STATUS_NOT_SAME_DEVICE;
3760                 goto out;
3761         }
3762
3763         status = parent_pathref(talloc_tos(),
3764                                 conn->cwd_fsp,
3765                                 smb_fname_old,
3766                                 &parent_fname_old,
3767                                 &base_name_old);
3768         if (!NT_STATUS_IS_OK(status)) {
3769                 goto out;
3770         }
3771
3772         status = parent_pathref(talloc_tos(),
3773                                 conn->cwd_fsp,
3774                                 smb_fname_new,
3775                                 &parent_fname_new,
3776                                 &base_name_new);
3777         if (!NT_STATUS_IS_OK(status)) {
3778                 goto out;
3779         }
3780
3781         if (VALID_STAT(smb_fname_new->st)) {
3782                 if (overwrite_if_exists) {
3783                         if (S_ISDIR(smb_fname_new->st.st_ex_mode)) {
3784                                 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3785                                 goto out;
3786                         }
3787                         status = unlink_internals(conn,
3788                                                 req,
3789                                                 FILE_ATTRIBUTE_NORMAL,
3790                                                 NULL, /* new_dirfsp */
3791                                                 smb_fname_new);
3792                         if (!NT_STATUS_IS_OK(status)) {
3793                                 goto out;
3794                         }
3795                 } else {
3796                         /* Disallow if newname already exists. */
3797                         status = NT_STATUS_OBJECT_NAME_COLLISION;
3798                         goto out;
3799                 }
3800         }
3801
3802         DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
3803                   smb_fname_old->base_name, smb_fname_new->base_name));
3804
3805         ret = SMB_VFS_LINKAT(conn,
3806                         parent_fname_old->fsp,
3807                         base_name_old,
3808                         parent_fname_new->fsp,
3809                         base_name_new,
3810                         0);
3811
3812         if (ret != 0) {
3813                 status = map_nt_error_from_unix(errno);
3814                 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3815                          nt_errstr(status), smb_fname_old->base_name,
3816                          smb_fname_new->base_name));
3817         }
3818
3819   out:
3820
3821         TALLOC_FREE(parent_fname_old);
3822         TALLOC_FREE(parent_fname_new);
3823         return status;
3824 }
3825
3826 /****************************************************************************
3827  Deal with setting the time from any of the setfilepathinfo functions.
3828  NOTE !!!! The check for FILE_WRITE_ATTRIBUTES access must be done *before*
3829  calling this function.
3830 ****************************************************************************/
3831
3832 NTSTATUS smb_set_file_time(connection_struct *conn,
3833                            files_struct *fsp,
3834                            struct smb_filename *smb_fname,
3835                            struct smb_file_time *ft,
3836                            bool setting_write_time)
3837 {
3838         struct files_struct *set_fsp = NULL;
3839         struct timeval_buf tbuf[4];
3840         uint32_t action =
3841                 FILE_NOTIFY_CHANGE_LAST_ACCESS
3842                 |FILE_NOTIFY_CHANGE_LAST_WRITE
3843                 |FILE_NOTIFY_CHANGE_CREATION;
3844         int ret;
3845
3846         if (!VALID_STAT(smb_fname->st)) {
3847                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3848         }
3849
3850         if (fsp == NULL) {
3851                 /* A symlink */
3852                 return NT_STATUS_OK;
3853         }
3854
3855         set_fsp = metadata_fsp(fsp);
3856
3857         /* get some defaults (no modifications) if any info is zero or -1. */
3858         if (is_omit_timespec(&ft->create_time)) {
3859                 action &= ~FILE_NOTIFY_CHANGE_CREATION;
3860         }
3861
3862         if (is_omit_timespec(&ft->atime)) {
3863                 action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
3864         }
3865
3866         if (is_omit_timespec(&ft->mtime)) {
3867                 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
3868         }
3869
3870         if (!setting_write_time) {
3871                 /* ft->mtime comes from change time, not write time. */
3872                 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
3873         }
3874
3875         /* Ensure the resolution is the correct for
3876          * what we can store on this filesystem. */
3877
3878         round_timespec(conn->ts_res, &ft->create_time);
3879         round_timespec(conn->ts_res, &ft->ctime);
3880         round_timespec(conn->ts_res, &ft->atime);
3881         round_timespec(conn->ts_res, &ft->mtime);
3882
3883         DBG_DEBUG("smb_set_filetime: actime: %s\n ",
3884                   timespec_string_buf(&ft->atime, true, &tbuf[0]));
3885         DBG_DEBUG("smb_set_filetime: modtime: %s\n ",
3886                   timespec_string_buf(&ft->mtime, true, &tbuf[1]));
3887         DBG_DEBUG("smb_set_filetime: ctime: %s\n ",
3888                   timespec_string_buf(&ft->ctime, true, &tbuf[2]));
3889         DBG_DEBUG("smb_set_file_time: createtime: %s\n ",
3890                   timespec_string_buf(&ft->create_time, true, &tbuf[3]));
3891
3892         if (setting_write_time) {
3893                 /*
3894                  * This was a Windows setfileinfo on an open file.
3895                  * NT does this a lot. We also need to
3896                  * set the time here, as it can be read by
3897                  * FindFirst/FindNext and with the patch for bug #2045
3898                  * in smbd/fileio.c it ensures that this timestamp is
3899                  * kept sticky even after a write. We save the request
3900                  * away and will set it on file close and after a write. JRA.
3901                  */
3902
3903                 DBG_DEBUG("setting pending modtime to %s\n",
3904                           timespec_string_buf(&ft->mtime, true, &tbuf[0]));
3905
3906                 if (set_fsp != NULL) {
3907                         set_sticky_write_time_fsp(set_fsp, ft->mtime);
3908                 } else {
3909                         set_sticky_write_time_path(
3910                                 vfs_file_id_from_sbuf(conn, &smb_fname->st),
3911                                 ft->mtime);
3912                 }
3913         }
3914
3915         DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
3916
3917         ret = file_ntimes(conn, set_fsp, ft);
3918         if (ret != 0) {
3919                 return map_nt_error_from_unix(errno);
3920         }
3921
3922         notify_fname(conn, NOTIFY_ACTION_MODIFIED, action,
3923                      smb_fname->base_name);
3924         return NT_STATUS_OK;
3925 }
3926
3927 /****************************************************************************
3928  Deal with setting the dosmode from any of the setfilepathinfo functions.
3929  NB. The check for FILE_WRITE_ATTRIBUTES access on this path must have been
3930  done before calling this function.
3931 ****************************************************************************/
3932
3933 static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
3934                                      struct files_struct *fsp,
3935                                      uint32_t dosmode)
3936 {
3937         struct files_struct *dos_fsp = NULL;
3938         uint32_t current_dosmode;
3939         int ret;
3940
3941         if (!VALID_STAT(fsp->fsp_name->st)) {
3942                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3943         }
3944
3945         dos_fsp = metadata_fsp(fsp);
3946
3947         if (dosmode != 0) {
3948                 if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
3949                         dosmode |= FILE_ATTRIBUTE_DIRECTORY;
3950                 } else {
3951                         dosmode &= ~FILE_ATTRIBUTE_DIRECTORY;
3952                 }
3953         }
3954
3955         DBG_DEBUG("dosmode: 0x%" PRIx32 "\n", dosmode);
3956
3957         /* check the mode isn't different, before changing it */
3958         if (dosmode == 0) {
3959                 return NT_STATUS_OK;
3960         }
3961         current_dosmode = fdos_mode(dos_fsp);
3962         if (dosmode == current_dosmode) {
3963                 return NT_STATUS_OK;
3964         }
3965
3966         DBG_DEBUG("file %s : setting dos mode 0x%" PRIx32 "\n",
3967                   fsp_str_dbg(dos_fsp), dosmode);
3968
3969         ret = file_set_dosmode(conn, dos_fsp->fsp_name, dosmode, NULL, false);
3970         if (ret != 0) {
3971                 DBG_WARNING("file_set_dosmode of %s failed: %s\n",
3972                             fsp_str_dbg(dos_fsp), strerror(errno));
3973                 return map_nt_error_from_unix(errno);
3974         }
3975
3976         return NT_STATUS_OK;
3977 }
3978
3979 /****************************************************************************
3980  Deal with setting the size from any of the setfilepathinfo functions.
3981 ****************************************************************************/
3982
3983 NTSTATUS smb_set_file_size(connection_struct *conn,
3984                            struct smb_request *req,
3985                            files_struct *fsp,
3986                            struct smb_filename *smb_fname,
3987                            const SMB_STRUCT_STAT *psbuf,
3988                            off_t size,
3989                            bool fail_after_createfile)
3990 {
3991         NTSTATUS status = NT_STATUS_OK;
3992         files_struct *new_fsp = NULL;
3993
3994         if (!VALID_STAT(*psbuf)) {
3995                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3996         }
3997
3998         DBG_INFO("size: %"PRIu64", file_size_stat=%"PRIu64"\n",
3999                  (uint64_t)size,
4000                  get_file_size_stat(psbuf));
4001
4002         if (size == get_file_size_stat(psbuf)) {
4003                 if (fsp == NULL) {
4004                         return NT_STATUS_OK;
4005                 }
4006                 if (!fsp->fsp_flags.modified) {
4007                         return NT_STATUS_OK;
4008                 }
4009                 trigger_write_time_update_immediate(fsp);
4010                 return NT_STATUS_OK;
4011         }
4012
4013         DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
4014                   smb_fname_str_dbg(smb_fname), (double)size));
4015
4016         if (fsp &&
4017             !fsp->fsp_flags.is_pathref &&
4018             fsp_get_io_fd(fsp) != -1)
4019         {
4020                 /* Handle based call. */
4021                 if (!(fsp->access_mask & FILE_WRITE_DATA)) {
4022                         return NT_STATUS_ACCESS_DENIED;
4023                 }
4024
4025                 if (vfs_set_filelen(fsp, size) == -1) {
4026                         return map_nt_error_from_unix(errno);
4027                 }
4028                 trigger_write_time_update_immediate(fsp);
4029                 return NT_STATUS_OK;
4030         }
4031
4032         status = SMB_VFS_CREATE_FILE(
4033                 conn,                                   /* conn */
4034                 req,                                    /* req */
4035                 NULL,                                   /* dirfsp */
4036                 smb_fname,                              /* fname */
4037                 FILE_WRITE_DATA,                        /* access_mask */
4038                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
4039                     FILE_SHARE_DELETE),
4040                 FILE_OPEN,                              /* create_disposition*/
4041                 0,                                      /* create_options */
4042                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
4043                 0,                                      /* oplock_request */
4044                 NULL,                                   /* lease */
4045                 0,                                      /* allocation_size */
4046                 0,                                      /* private_flags */
4047                 NULL,                                   /* sd */
4048                 NULL,                                   /* ea_list */
4049                 &new_fsp,                               /* result */
4050                 NULL,                                   /* pinfo */
4051                 NULL, NULL);                            /* create context */
4052
4053         if (!NT_STATUS_IS_OK(status)) {
4054                 /* NB. We check for open_was_deferred in the caller. */
4055                 return status;
4056         }
4057
4058         /* See RAW-SFILEINFO-END-OF-FILE */
4059         if (fail_after_createfile) {
4060                 close_file_free(req, &new_fsp, NORMAL_CLOSE);
4061                 return NT_STATUS_INVALID_LEVEL;
4062         }
4063
4064         if (vfs_set_filelen(new_fsp, size) == -1) {
4065                 status = map_nt_error_from_unix(errno);
4066                 close_file_free(req, &new_fsp, NORMAL_CLOSE);
4067                 return status;
4068         }
4069
4070         trigger_write_time_update_immediate(new_fsp);
4071         close_file_free(req, &new_fsp, NORMAL_CLOSE);
4072         return NT_STATUS_OK;
4073 }
4074
4075 /****************************************************************************
4076  Deal with SMB_INFO_SET_EA.
4077 ****************************************************************************/
4078
4079 static NTSTATUS smb_info_set_ea(connection_struct *conn,
4080                                 const char *pdata,
4081                                 int total_data,
4082                                 files_struct *fsp,
4083                                 struct smb_filename *smb_fname)
4084 {
4085         struct ea_list *ea_list = NULL;
4086         TALLOC_CTX *ctx = NULL;
4087         NTSTATUS status = NT_STATUS_OK;
4088
4089         if (total_data < 10) {
4090
4091                 /* OS/2 workplace shell seems to send SET_EA requests of "null"
4092                    length. They seem to have no effect. Bug #3212. JRA */
4093
4094                 if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
4095                         /* We're done. We only get EA info in this call. */
4096                         return NT_STATUS_OK;
4097                 }
4098
4099                 return NT_STATUS_INVALID_PARAMETER;
4100         }
4101
4102         if (IVAL(pdata,0) > total_data) {
4103                 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
4104                         IVAL(pdata,0), (unsigned int)total_data));
4105                 return NT_STATUS_INVALID_PARAMETER;
4106         }
4107
4108         ctx = talloc_tos();
4109         ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
4110         if (!ea_list) {
4111                 return NT_STATUS_INVALID_PARAMETER;
4112         }
4113
4114         if (fsp == NULL) {
4115                 /*
4116                  * The only way fsp can be NULL here is if
4117                  * smb_fname points at a symlink and
4118                  * and we're in POSIX context.
4119                  * Ensure this is the case.
4120                  *
4121                  * In this case we cannot set the EA.
4122                  */
4123                 SMB_ASSERT(smb_fname->flags & SMB_FILENAME_POSIX_PATH);
4124                 return NT_STATUS_ACCESS_DENIED;
4125         }
4126
4127         status = set_ea(conn, fsp, ea_list);
4128
4129         return status;
4130 }
4131
4132 /****************************************************************************
4133  Deal with SMB_FILE_FULL_EA_INFORMATION set.
4134 ****************************************************************************/
4135
4136 static NTSTATUS smb_set_file_full_ea_info(connection_struct *conn,
4137                                 const char *pdata,
4138                                 int total_data,
4139                                 files_struct *fsp)
4140 {
4141         struct ea_list *ea_list = NULL;
4142         NTSTATUS status;
4143
4144         if (fsp == NULL) {
4145                 return NT_STATUS_INVALID_HANDLE;
4146         }
4147
4148         if (!lp_ea_support(SNUM(conn))) {
4149                 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
4150                         "EA's not supported.\n",
4151                         (unsigned int)total_data));
4152                 return NT_STATUS_EAS_NOT_SUPPORTED;
4153         }
4154
4155         if (total_data < 10) {
4156                 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
4157                         "too small.\n",
4158                         (unsigned int)total_data));
4159                 return NT_STATUS_INVALID_PARAMETER;
4160         }
4161
4162         ea_list = read_nttrans_ea_list(talloc_tos(),
4163                                 pdata,
4164                                 total_data);
4165
4166         if (!ea_list) {
4167                 return NT_STATUS_INVALID_PARAMETER;
4168         }
4169
4170         status = set_ea(conn, fsp, ea_list);
4171
4172         DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
4173                 smb_fname_str_dbg(fsp->fsp_name),
4174                 nt_errstr(status) ));
4175
4176         return status;
4177 }
4178
4179
4180 /****************************************************************************
4181  Deal with SMB_SET_FILE_DISPOSITION_INFO.
4182 ****************************************************************************/
4183
4184 NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
4185                                        const char *pdata,
4186                                        int total_data,
4187                                        files_struct *fsp,
4188                                        struct smb_filename *smb_fname)
4189 {
4190         NTSTATUS status = NT_STATUS_OK;
4191         bool delete_on_close;
4192         uint32_t dosmode = 0;
4193
4194         if (total_data < 1) {
4195                 return NT_STATUS_INVALID_PARAMETER;
4196         }
4197
4198         if (fsp == NULL) {
4199                 return NT_STATUS_INVALID_HANDLE;
4200         }
4201
4202         delete_on_close = (CVAL(pdata,0) ? True : False);
4203         dosmode = fdos_mode(fsp);
4204
4205         DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
4206                 "delete_on_close = %u\n",
4207                 smb_fname_str_dbg(smb_fname),
4208                 (unsigned int)dosmode,
4209                 (unsigned int)delete_on_close ));
4210
4211         if (delete_on_close) {
4212                 status = can_set_delete_on_close(fsp, dosmode);
4213                 if (!NT_STATUS_IS_OK(status)) {
4214                         return status;
4215                 }
4216         }
4217
4218         /* The set is across all open files on this dev/inode pair. */
4219         if (!set_delete_on_close(fsp, delete_on_close,
4220                                  conn->session_info->security_token,
4221                                  conn->session_info->unix_token)) {
4222                 return NT_STATUS_ACCESS_DENIED;
4223         }
4224         return NT_STATUS_OK;
4225 }
4226
4227 /****************************************************************************
4228  Deal with SMB_FILE_POSITION_INFORMATION.
4229 ****************************************************************************/
4230
4231 static NTSTATUS smb_file_position_information(connection_struct *conn,
4232                                 const char *pdata,
4233                                 int total_data,
4234                                 files_struct *fsp)
4235 {
4236         uint64_t position_information;
4237
4238         if (total_data < 8) {
4239                 return NT_STATUS_INVALID_PARAMETER;
4240         }
4241
4242         if (fsp == NULL) {
4243                 /* Ignore on pathname based set. */
4244                 return NT_STATUS_OK;
4245         }
4246
4247         position_information = (uint64_t)IVAL(pdata,0);
4248         position_information |= (((uint64_t)IVAL(pdata,4)) << 32);
4249
4250         DEBUG(10,("smb_file_position_information: Set file position "
4251                   "information for file %s to %.0f\n", fsp_str_dbg(fsp),
4252                   (double)position_information));
4253         fh_set_position_information(fsp->fh, position_information);
4254         return NT_STATUS_OK;
4255 }
4256
4257 /****************************************************************************
4258  Deal with SMB_FILE_MODE_INFORMATION.
4259 ****************************************************************************/
4260
4261 static NTSTATUS smb_file_mode_information(connection_struct *conn,
4262                                 const char *pdata,
4263                                 int total_data)
4264 {
4265         uint32_t mode;
4266
4267         if (total_data < 4) {
4268                 return NT_STATUS_INVALID_PARAMETER;
4269         }
4270         mode = IVAL(pdata,0);
4271         if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
4272                 return NT_STATUS_INVALID_PARAMETER;
4273         }
4274         return NT_STATUS_OK;
4275 }
4276
4277 /****************************************************************************
4278  Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
4279 ****************************************************************************/
4280
4281 static NTSTATUS smb2_file_rename_information(connection_struct *conn,
4282                                             struct smb_request *req,
4283                                             const char *pdata,
4284                                             int total_data,
4285                                             files_struct *fsp,
4286                                             struct smb_filename *smb_fname_src)
4287 {
4288         bool overwrite;
4289         uint32_t len;
4290         char *newname = NULL;
4291         struct files_struct *dst_dirfsp = NULL;
4292         struct smb_filename *smb_fname_dst = NULL;
4293         const char *dst_original_lcomp = NULL;
4294         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
4295         NTSTATUS status = NT_STATUS_OK;
4296         TALLOC_CTX *ctx = talloc_tos();
4297
4298         if (!fsp) {
4299                 return NT_STATUS_INVALID_HANDLE;
4300         }
4301
4302         if (total_data < 20) {
4303                 return NT_STATUS_INVALID_PARAMETER;
4304         }
4305
4306         overwrite = (CVAL(pdata,0) ? True : False);
4307         len = IVAL(pdata,16);
4308
4309         if (len > (total_data - 20) || (len == 0)) {
4310                 return NT_STATUS_INVALID_PARAMETER;
4311         }
4312
4313         (void)srvstr_pull_talloc(ctx,
4314                                  pdata,
4315                                  req->flags2,
4316                                  &newname,
4317                                  &pdata[20],
4318                                  len,
4319                                  STR_TERMINATE);
4320
4321         if (newname == NULL) {
4322                 return NT_STATUS_INVALID_PARAMETER;
4323         }
4324
4325         /* SMB2 rename paths are never DFS. */
4326         req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
4327         ucf_flags &= ~UCF_DFS_PATHNAME;
4328
4329         status = check_path_syntax(newname,
4330                         fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
4331         if (!NT_STATUS_IS_OK(status)) {
4332                 return status;
4333         }
4334
4335         DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
4336                                 newname));
4337
4338         if (newname[0] == ':') {
4339                 /* Create an smb_fname to call rename_internals_fsp() with. */
4340                 smb_fname_dst = synthetic_smb_fname(talloc_tos(),
4341                                         fsp->base_fsp->fsp_name->base_name,
4342                                         newname,
4343                                         NULL,
4344                                         fsp->base_fsp->fsp_name->twrp,
4345                                         fsp->base_fsp->fsp_name->flags);
4346                 if (smb_fname_dst == NULL) {
4347                         status = NT_STATUS_NO_MEMORY;
4348                         goto out;
4349                 }
4350         } else {
4351                 status = filename_convert_dirfsp(ctx,
4352                                                  conn,
4353                                                  newname,
4354                                                  ucf_flags,
4355                                                  0, /* Never a TWRP. */
4356                                                  &dst_dirfsp,
4357                                                  &smb_fname_dst);
4358                 if (!NT_STATUS_IS_OK(status)) {
4359                         goto out;
4360                 }
4361         }
4362
4363         /*
4364          * Set the original last component, since
4365          * rename_internals_fsp() requires it.
4366          */
4367         dst_original_lcomp = get_original_lcomp(smb_fname_dst,
4368                                         conn,
4369                                         newname,
4370                                         ucf_flags);
4371         if (dst_original_lcomp == NULL) {
4372                 status = NT_STATUS_NO_MEMORY;
4373                 goto out;
4374         }
4375
4376         DEBUG(10,("smb2_file_rename_information: "
4377                   "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
4378                   fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
4379                   smb_fname_str_dbg(smb_fname_dst)));
4380         status = rename_internals_fsp(conn,
4381                                 fsp,
4382                                 smb_fname_dst,
4383                                 dst_original_lcomp,
4384                                 (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM),
4385                                 overwrite);
4386
4387  out:
4388         TALLOC_FREE(smb_fname_dst);
4389         return status;
4390 }
4391
4392 static NTSTATUS smb2_file_link_information(connection_struct *conn,
4393                                             struct smb_request *req,
4394                                             const char *pdata,
4395                                             int total_data,
4396                                             files_struct *fsp,
4397                                             struct smb_filename *smb_fname_src)
4398 {
4399         bool overwrite;
4400         uint32_t len;
4401         char *newname = NULL;
4402         struct files_struct *dst_dirfsp = NULL;
4403         struct smb_filename *smb_fname_dst = NULL;
4404         NTSTATUS status = NT_STATUS_OK;
4405         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
4406         size_t ret;
4407         TALLOC_CTX *ctx = talloc_tos();
4408
4409         if (!fsp) {
4410                 return NT_STATUS_INVALID_HANDLE;
4411         }
4412
4413         if (total_data < 20) {
4414                 return NT_STATUS_INVALID_PARAMETER;
4415         }
4416
4417         overwrite = (CVAL(pdata,0) ? true : false);
4418         len = IVAL(pdata,16);
4419
4420         if (len > (total_data - 20) || (len == 0)) {
4421                 return NT_STATUS_INVALID_PARAMETER;
4422         }
4423
4424         ret = srvstr_pull_talloc(ctx,
4425                                  pdata,
4426                                  req->flags2,
4427                                  &newname,
4428                                  &pdata[20],
4429                                  len,
4430                                  STR_TERMINATE);
4431
4432         if (ret == (size_t)-1 || newname == NULL) {
4433                 return NT_STATUS_INVALID_PARAMETER;
4434         }
4435
4436         /* SMB2 hardlink paths are never DFS. */
4437         req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
4438         ucf_flags &= ~UCF_DFS_PATHNAME;
4439
4440         status = check_path_syntax(newname,
4441                         fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
4442         if (!NT_STATUS_IS_OK(status)) {
4443                 return status;
4444         }
4445
4446         DBG_DEBUG("got name |%s|\n", newname);
4447
4448         status = filename_convert_dirfsp(ctx,
4449                                          conn,
4450                                          newname,
4451                                          ucf_flags,
4452                                          0, /* No TWRP. */
4453                                          &dst_dirfsp,
4454                                          &smb_fname_dst);
4455         if (!NT_STATUS_IS_OK(status)) {
4456                 return status;
4457         }
4458
4459         if (fsp->base_fsp) {
4460                 /* No stream names. */
4461                 return NT_STATUS_NOT_SUPPORTED;
4462         }
4463
4464         DBG_DEBUG("SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
4465                   fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
4466                   smb_fname_str_dbg(smb_fname_dst));
4467         status = hardlink_internals(ctx,
4468                                 conn,
4469                                 req,
4470                                 overwrite,
4471                                 fsp->fsp_name,
4472                                 smb_fname_dst);
4473
4474         TALLOC_FREE(smb_fname_dst);
4475         return status;
4476 }
4477
4478 static NTSTATUS smb_file_link_information(connection_struct *conn,
4479                                             struct smb_request *req,
4480                                             const char *pdata,
4481                                             int total_data,
4482                                             files_struct *fsp,
4483                                             struct smb_filename *smb_fname_src)
4484 {
4485         bool overwrite;
4486         uint32_t len;
4487         char *newname = NULL;
4488         struct files_struct *dst_dirfsp = NULL;
4489         struct smb_filename *smb_fname_dst = NULL;
4490         NTSTATUS status = NT_STATUS_OK;
4491         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
4492         NTTIME dst_twrp = 0;
4493         TALLOC_CTX *ctx = talloc_tos();
4494
4495         if (!fsp) {
4496                 return NT_STATUS_INVALID_HANDLE;
4497         }
4498
4499         if (total_data < 20) {
4500                 return NT_STATUS_INVALID_PARAMETER;
4501         }
4502
4503         overwrite = (CVAL(pdata,0) ? true : false);
4504         len = IVAL(pdata,16);
4505
4506         if (len > (total_data - 20) || (len == 0)) {
4507                 return NT_STATUS_INVALID_PARAMETER;
4508         }
4509
4510         if (smb_fname_src->flags & SMB_FILENAME_POSIX_PATH) {
4511                 srvstr_get_path_posix(ctx,
4512                                 pdata,
4513                                 req->flags2,
4514                                 &newname,
4515                                 &pdata[20],
4516                                 len,
4517                                 STR_TERMINATE,
4518                                 &status);
4519                 ucf_flags |= UCF_POSIX_PATHNAMES;
4520         } else {
4521                 srvstr_get_path(ctx,
4522                                 pdata,
4523                                 req->flags2,
4524                                 &newname,
4525                                 &pdata[20],
4526                                 len,
4527                                 STR_TERMINATE,
4528                                 &status);
4529         }
4530         if (!NT_STATUS_IS_OK(status)) {
4531                 return status;
4532         }
4533
4534         DEBUG(10,("smb_file_link_information: got name |%s|\n",
4535                                 newname));
4536
4537         if (ucf_flags & UCF_GMT_PATHNAME) {
4538                 extract_snapshot_token(newname, &dst_twrp);
4539         }
4540         /* hardlink paths are never DFS. */
4541         ucf_flags &= ~UCF_DFS_PATHNAME;
4542
4543         status = filename_convert_dirfsp(ctx,
4544                                          conn,
4545                                          newname,
4546                                          ucf_flags,
4547                                          dst_twrp,
4548                                          &dst_dirfsp,
4549                                          &smb_fname_dst);
4550         if (!NT_STATUS_IS_OK(status)) {
4551                 return status;
4552         }
4553
4554         if (fsp->base_fsp) {
4555                 /* No stream names. */
4556                 return NT_STATUS_NOT_SUPPORTED;
4557         }
4558
4559         DEBUG(10,("smb_file_link_information: "
4560                   "SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
4561                   fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
4562                   smb_fname_str_dbg(smb_fname_dst)));
4563         status = hardlink_internals(ctx,
4564                                 conn,
4565                                 req,
4566                                 overwrite,
4567                                 fsp->fsp_name,
4568                                 smb_fname_dst);
4569
4570         TALLOC_FREE(smb_fname_dst);
4571         return status;
4572 }
4573
4574
4575 /****************************************************************************
4576  Deal with SMB_FILE_RENAME_INFORMATION.
4577 ****************************************************************************/
4578
4579 static NTSTATUS smb_file_rename_information(connection_struct *conn,
4580                                             struct smb_request *req,
4581                                             const char *pdata,
4582                                             int total_data,
4583                                             files_struct *fsp,
4584                                             struct smb_filename *smb_fname_src)
4585 {
4586         bool overwrite;
4587         uint32_t root_fid;
4588         uint32_t len;
4589         char *newname = NULL;
4590         struct files_struct *dst_dirfsp = NULL;
4591         struct smb_filename *smb_fname_dst = NULL;
4592         const char *dst_original_lcomp = NULL;
4593         NTSTATUS status = NT_STATUS_OK;
4594         char *p;
4595         TALLOC_CTX *ctx = talloc_tos();
4596
4597         if (total_data < 13) {
4598                 return NT_STATUS_INVALID_PARAMETER;
4599         }
4600
4601         overwrite = (CVAL(pdata,0) != 0);
4602         root_fid = IVAL(pdata,4);
4603         len = IVAL(pdata,8);
4604
4605         if (len > (total_data - 12) || (len == 0) || (root_fid != 0)) {
4606                 return NT_STATUS_INVALID_PARAMETER;
4607         }
4608
4609         if (req->posix_pathnames) {
4610                 srvstr_get_path_posix(ctx,
4611                                 pdata,
4612                                 req->flags2,
4613                                 &newname,
4614                                 &pdata[12],
4615                                 len,
4616                                 0,
4617                                 &status);
4618         } else {
4619                 srvstr_get_path(ctx,
4620                                 pdata,
4621                                 req->flags2,
4622                                 &newname,
4623                                 &pdata[12],
4624                                 len,
4625                                 0,
4626                                 &status);
4627         }
4628         if (!NT_STATUS_IS_OK(status)) {
4629                 return status;
4630         }
4631
4632         DEBUG(10,("smb_file_rename_information: got name |%s|\n",
4633                                 newname));
4634
4635         /* Check the new name has no '/' characters. */
4636         if (strchr_m(newname, '/')) {
4637                 return NT_STATUS_NOT_SUPPORTED;
4638         }
4639
4640         if (fsp && fsp->base_fsp) {
4641                 /* newname must be a stream name. */
4642                 if (newname[0] != ':') {
4643                         return NT_STATUS_NOT_SUPPORTED;
4644                 }
4645
4646                 /* Create an smb_fname to call rename_internals_fsp() with. */
4647                 smb_fname_dst = synthetic_smb_fname(talloc_tos(),
4648                                         fsp->base_fsp->fsp_name->base_name,
4649                                         newname,
4650                                         NULL,
4651                                         fsp->base_fsp->fsp_name->twrp,
4652                                         fsp->base_fsp->fsp_name->flags);
4653                 if (smb_fname_dst == NULL) {
4654                         status = NT_STATUS_NO_MEMORY;
4655                         goto out;
4656                 }
4657
4658                 /*
4659                  * Get the original last component, since
4660                  * rename_internals_fsp() requires it.
4661                  */
4662                 dst_original_lcomp = get_original_lcomp(smb_fname_dst,
4663                                         conn,
4664                                         newname,
4665                                         0);
4666                 if (dst_original_lcomp == NULL) {
4667                         status = NT_STATUS_NO_MEMORY;
4668                         goto out;
4669                 }
4670
4671         } else {
4672                 /*
4673                  * Build up an smb_fname_dst based on the filename passed in.
4674                  * We basically just strip off the last component, and put on
4675                  * the newname instead.
4676                  */
4677                 char *base_name = NULL;
4678                 uint32_t ucf_flags = ucf_flags_from_smb_request(req);
4679                 NTTIME dst_twrp = 0;
4680
4681                 /* newname must *not* be a stream name. */
4682                 if (newname[0] == ':') {
4683                         return NT_STATUS_NOT_SUPPORTED;
4684                 }
4685
4686                 /*
4687                  * Strip off the last component (filename) of the path passed
4688                  * in.
4689                  */
4690                 base_name = talloc_strdup(ctx, smb_fname_src->base_name);
4691                 if (!base_name) {
4692                         return NT_STATUS_NO_MEMORY;
4693                 }
4694                 p = strrchr_m(base_name, '/');
4695                 if (p) {
4696                         p[1] = '\0';
4697                 } else {
4698                         base_name = talloc_strdup(ctx, "");
4699                         if (!base_name) {
4700                                 return NT_STATUS_NO_MEMORY;
4701                         }
4702                 }
4703                 /* Append the new name. */
4704                 base_name = talloc_asprintf_append(base_name,
4705                                 "%s",
4706                                 newname);
4707                 if (!base_name) {
4708                         return NT_STATUS_NO_MEMORY;
4709                 }
4710
4711                 if (ucf_flags & UCF_GMT_PATHNAME) {
4712                         extract_snapshot_token(base_name, &dst_twrp);
4713                 }
4714
4715                 /* The newname is *not* a DFS path. */
4716                 ucf_flags &= ~UCF_DFS_PATHNAME;
4717
4718                 status = filename_convert_dirfsp(ctx,
4719                                          conn,
4720                                          base_name,
4721                                          ucf_flags,
4722                                          dst_twrp,
4723                                          &dst_dirfsp,
4724                                          &smb_fname_dst);
4725
4726                 if (!NT_STATUS_IS_OK(status)) {
4727                         goto out;
4728                 }
4729                 dst_original_lcomp = get_original_lcomp(smb_fname_dst,
4730                                         conn,
4731                                         newname,
4732                                         ucf_flags);
4733                 if (dst_original_lcomp == NULL) {
4734                         status = NT_STATUS_NO_MEMORY;
4735                         goto out;
4736                 }
4737         }
4738
4739         if (fsp != NULL && fsp->fsp_flags.is_fsa) {
4740                 DEBUG(10,("smb_file_rename_information: "
4741                           "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
4742                           fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
4743                           smb_fname_str_dbg(smb_fname_dst)));
4744                 status = rename_internals_fsp(conn,
4745                                         fsp,
4746                                         smb_fname_dst,
4747                                         dst_original_lcomp,
4748                                         0,
4749                                         overwrite);
4750         } else {
4751                 DEBUG(10,("smb_file_rename_information: "
4752                           "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
4753                           smb_fname_str_dbg(smb_fname_src),
4754                           smb_fname_str_dbg(smb_fname_dst)));
4755                 status = rename_internals(ctx,
4756                                         conn,
4757                                         req,
4758                                         NULL, /* src_dirfsp */
4759                                         smb_fname_src,
4760                                         smb_fname_dst,
4761                                         dst_original_lcomp,
4762                                         0,
4763                                         overwrite,
4764                                         FILE_WRITE_ATTRIBUTES);
4765         }
4766  out:
4767         TALLOC_FREE(smb_fname_dst);
4768         return status;
4769 }
4770
4771 /****************************************************************************
4772  Deal with SMB_SET_FILE_BASIC_INFO.
4773 ****************************************************************************/
4774
4775 static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
4776                                         const char *pdata,
4777                                         int total_data,
4778                                         files_struct *fsp,
4779                                         struct smb_filename *smb_fname)
4780 {
4781         /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
4782         struct smb_file_time ft;
4783         uint32_t dosmode = 0;
4784         NTSTATUS status = NT_STATUS_OK;
4785
4786         init_smb_file_time(&ft);
4787
4788         if (total_data < 36) {
4789                 return NT_STATUS_INVALID_PARAMETER;
4790         }
4791
4792         if (fsp == NULL) {
4793                 return NT_STATUS_INVALID_HANDLE;
4794         }
4795
4796         status = check_any_access_fsp(fsp, FILE_WRITE_ATTRIBUTES);
4797         if (!NT_STATUS_IS_OK(status)) {
4798                 return status;
4799         }
4800
4801         /* Set the attributes */
4802         dosmode = IVAL(pdata,32);
4803         status = smb_set_file_dosmode(conn, fsp, dosmode);
4804         if (!NT_STATUS_IS_OK(status)) {
4805                 return status;
4806         }
4807
4808         /* create time */
4809         ft.create_time = pull_long_date_full_timespec(pdata);
4810
4811         /* access time */
4812         ft.atime = pull_long_date_full_timespec(pdata+8);
4813
4814         /* write time. */
4815         ft.mtime = pull_long_date_full_timespec(pdata+16);
4816
4817         /* change time. */
4818         ft.ctime = pull_long_date_full_timespec(pdata+24);
4819
4820         DEBUG(10, ("smb_set_file_basic_info: file %s\n",
4821                    smb_fname_str_dbg(smb_fname)));
4822
4823         status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
4824         if (!NT_STATUS_IS_OK(status)) {
4825                 return status;
4826         }
4827
4828         if (fsp->fsp_flags.modified) {
4829                 trigger_write_time_update_immediate(fsp);
4830         }
4831         return NT_STATUS_OK;
4832 }
4833
4834 /****************************************************************************
4835  Deal with SMB_INFO_STANDARD.
4836 ****************************************************************************/
4837
4838 static NTSTATUS smb_set_info_standard(connection_struct *conn,
4839                                         const char *pdata,
4840                                         int total_data,
4841                                         files_struct *fsp,
4842                                         struct smb_filename *smb_fname)
4843 {
4844         NTSTATUS status;
4845         struct smb_file_time ft;
4846
4847         init_smb_file_time(&ft);
4848
4849         if (total_data < 12) {
4850                 return NT_STATUS_INVALID_PARAMETER;
4851         }
4852
4853         if (fsp == NULL) {
4854                 return NT_STATUS_INVALID_HANDLE;
4855         }
4856
4857         /* create time */
4858         ft.create_time = time_t_to_full_timespec(srv_make_unix_date2(pdata));
4859         /* access time */
4860         ft.atime = time_t_to_full_timespec(srv_make_unix_date2(pdata+4));
4861         /* write time */
4862         ft.mtime = time_t_to_full_timespec(srv_make_unix_date2(pdata+8));
4863
4864         DEBUG(10,("smb_set_info_standard: file %s\n",
4865                 smb_fname_str_dbg(smb_fname)));
4866
4867         status = check_any_access_fsp(fsp, FILE_WRITE_ATTRIBUTES);
4868         if (!NT_STATUS_IS_OK(status)) {
4869                 return status;
4870         }
4871
4872         status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
4873         if (!NT_STATUS_IS_OK(status)) {
4874                 return status;
4875         }
4876
4877         if (fsp->fsp_flags.modified) {
4878                 trigger_write_time_update_immediate(fsp);
4879         }
4880         return NT_STATUS_OK;
4881 }
4882
4883 /****************************************************************************
4884  Deal with SMB_SET_FILE_ALLOCATION_INFO.
4885 ****************************************************************************/
4886
4887 static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
4888                                              struct smb_request *req,
4889                                         const char *pdata,
4890                                         int total_data,
4891                                         files_struct *fsp,
4892                                         struct smb_filename *smb_fname)
4893 {
4894         uint64_t allocation_size = 0;
4895         NTSTATUS status = NT_STATUS_OK;
4896         files_struct *new_fsp = NULL;
4897
4898         if (!VALID_STAT(smb_fname->st)) {
4899                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4900         }
4901
4902         if (total_data < 8) {
4903                 return NT_STATUS_INVALID_PARAMETER;
4904         }
4905
4906         allocation_size = (uint64_t)IVAL(pdata,0);
4907         allocation_size |= (((uint64_t)IVAL(pdata,4)) << 32);
4908         DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
4909                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
4910                   (double)allocation_size));
4911
4912         if (allocation_size) {
4913                 allocation_size = smb_roundup(conn, allocation_size);
4914         }
4915
4916         DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
4917                   "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname),
4918                   (double)allocation_size));
4919
4920         if (fsp &&
4921             !fsp->fsp_flags.is_pathref &&
4922             fsp_get_io_fd(fsp) != -1)
4923         {
4924                 /* Open file handle. */
4925                 if (!(fsp->access_mask & FILE_WRITE_DATA)) {
4926                         return NT_STATUS_ACCESS_DENIED;
4927                 }
4928
4929                 /* Only change if needed. */
4930                 if (allocation_size != get_file_size_stat(&smb_fname->st)) {
4931                         if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
4932                                 return map_nt_error_from_unix(errno);
4933                         }
4934                 }
4935                 /* But always update the time. */
4936                 /*
4937                  * This is equivalent to a write. Ensure it's seen immediately
4938                  * if there are no pending writes.
4939                  */
4940                 trigger_write_time_update_immediate(fsp);
4941                 return NT_STATUS_OK;
4942         }
4943
4944         /* Pathname or stat or directory file. */
4945         status = SMB_VFS_CREATE_FILE(
4946                 conn,                                   /* conn */
4947                 req,                                    /* req */
4948                 NULL,                                   /* dirfsp */
4949                 smb_fname,                              /* fname */
4950                 FILE_WRITE_DATA,                        /* access_mask */
4951                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
4952                     FILE_SHARE_DELETE),
4953                 FILE_OPEN,                              /* create_disposition*/
4954                 0,                                      /* create_options */
4955                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
4956                 0,                                      /* oplock_request */
4957                 NULL,                                   /* lease */
4958                 0,                                      /* allocation_size */
4959                 0,                                      /* private_flags */
4960                 NULL,                                   /* sd */
4961                 NULL,                                   /* ea_list */
4962                 &new_fsp,                               /* result */
4963                 NULL,                                   /* pinfo */
4964                 NULL, NULL);                            /* create context */
4965
4966         if (!NT_STATUS_IS_OK(status)) {
4967                 /* NB. We check for open_was_deferred in the caller. */
4968                 return status;
4969         }
4970
4971         /* Only change if needed. */
4972         if (allocation_size != get_file_size_stat(&smb_fname->st)) {
4973                 if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
4974                         status = map_nt_error_from_unix(errno);
4975                         close_file_free(req, &new_fsp, NORMAL_CLOSE);
4976                         return status;
4977                 }
4978         }
4979
4980         /* Changing the allocation size should set the last mod time. */
4981         /*
4982          * This is equivalent to a write. Ensure it's seen immediately
4983          * if there are no pending writes.
4984          */
4985         trigger_write_time_update_immediate(new_fsp);
4986         close_file_free(req, &new_fsp, NORMAL_CLOSE);
4987         return NT_STATUS_OK;
4988 }
4989
4990 /****************************************************************************
4991  Deal with SMB_SET_FILE_END_OF_FILE_INFO.
4992 ****************************************************************************/
4993
4994 static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
4995                                               struct smb_request *req,
4996                                         const char *pdata,
4997                                         int total_data,
4998                                         files_struct *fsp,
4999                                         struct smb_filename *smb_fname,
5000                                         bool fail_after_createfile)
5001 {
5002         off_t size;
5003
5004         if (total_data < 8) {
5005                 return NT_STATUS_INVALID_PARAMETER;
5006         }
5007
5008         size = IVAL(pdata,0);
5009         size |= (((off_t)IVAL(pdata,4)) << 32);
5010         DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
5011                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
5012                   (double)size));
5013
5014         return smb_set_file_size(conn, req,
5015                                 fsp,
5016                                 smb_fname,
5017                                 &smb_fname->st,
5018                                 size,
5019                                 fail_after_createfile);
5020 }
5021
5022 NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
5023                                 struct smb_request *req,
5024                                 TALLOC_CTX *mem_ctx,
5025                                 uint16_t info_level,
5026                                 files_struct *fsp,
5027                                 struct smb_filename *smb_fname,
5028                                 char **ppdata, int total_data,
5029                                 int *ret_data_size)
5030 {
5031         char *pdata = *ppdata;
5032         NTSTATUS status = NT_STATUS_OK;
5033         int data_return_size = 0;
5034
5035         *ret_data_size = 0;
5036
5037         DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "
5038                  "totdata=%d\n", smb_fname_str_dbg(smb_fname),
5039                  fsp_fnum_dbg(fsp),
5040                  info_level, total_data));
5041
5042         switch (info_level) {
5043
5044                 case SMB_INFO_STANDARD:
5045                 {
5046                         status = smb_set_info_standard(conn,
5047                                         pdata,
5048                                         total_data,
5049                                         fsp,
5050                                         smb_fname);
5051                         break;
5052                 }
5053
5054                 case SMB_INFO_SET_EA:
5055                 {
5056                         status = smb_info_set_ea(conn,
5057                                                 pdata,
5058                                                 total_data,
5059                                                 fsp,
5060                                                 smb_fname);
5061                         break;
5062                 }
5063
5064                 case SMB_SET_FILE_BASIC_INFO:
5065                 case SMB_FILE_BASIC_INFORMATION:
5066                 {
5067                         status = smb_set_file_basic_info(conn,
5068                                                         pdata,
5069                                                         total_data,
5070                                                         fsp,
5071                                                         smb_fname);
5072                         break;
5073                 }
5074
5075                 case SMB_FILE_ALLOCATION_INFORMATION:
5076                 case SMB_SET_FILE_ALLOCATION_INFO:
5077                 {
5078                         status = smb_set_file_allocation_info(conn, req,
5079                                                                 pdata,
5080                                                                 total_data,
5081                                                                 fsp,
5082                                                                 smb_fname);
5083                         break;
5084                 }
5085
5086                 case SMB_FILE_END_OF_FILE_INFORMATION:
5087                 case SMB_SET_FILE_END_OF_FILE_INFO:
5088                 {
5089                         /*
5090                          * XP/Win7 both fail after the createfile with
5091                          * SMB_SET_FILE_END_OF_FILE_INFO but not
5092                          * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
5093                          * The level is known here, so pass it down
5094                          * appropriately.
5095                          */
5096                         bool should_fail =
5097                             (info_level == SMB_SET_FILE_END_OF_FILE_INFO);
5098
5099                         status = smb_set_file_end_of_file_info(conn, req,
5100                                                                 pdata,
5101                                                                 total_data,
5102                                                                 fsp,
5103                                                                 smb_fname,
5104                                                                 should_fail);
5105                         break;
5106                 }
5107
5108                 case SMB_FILE_DISPOSITION_INFORMATION:
5109                 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
5110                 {
5111 #if 0
5112                         /* JRA - We used to just ignore this on a path ?
5113                          * Shouldn't this be invalid level on a pathname
5114                          * based call ?
5115                          */
5116                         if (tran_call != TRANSACT2_SETFILEINFO) {
5117                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
5118                         }
5119 #endif
5120                         status = smb_set_file_disposition_info(conn,
5121                                                 pdata,
5122                                                 total_data,
5123                                                 fsp,
5124                                                 smb_fname);
5125                         break;
5126                 }
5127
5128                 case SMB_FILE_POSITION_INFORMATION:
5129                 {
5130                         status = smb_file_position_information(conn,
5131                                                 pdata,
5132                                                 total_data,
5133                                                 fsp);
5134                         break;
5135                 }
5136
5137                 case SMB_FILE_FULL_EA_INFORMATION:
5138                 {
5139                         status = smb_set_file_full_ea_info(conn,
5140                                                 pdata,
5141                                                 total_data,
5142                                                 fsp);
5143                         break;
5144                 }
5145
5146                 /* From tridge Samba4 :
5147                  * MODE_INFORMATION in setfileinfo (I have no
5148                  * idea what "mode information" on a file is - it takes a value of 0,
5149                  * 2, 4 or 6. What could it be?).
5150                  */
5151
5152                 case SMB_FILE_MODE_INFORMATION:
5153                 {
5154                         status = smb_file_mode_information(conn,
5155                                                 pdata,
5156                                                 total_data);
5157                         break;
5158                 }
5159
5160                 /* [MS-SMB2] 3.3.5.21.1 states we MUST fail with STATUS_NOT_SUPPORTED. */
5161                 case SMB_FILE_VALID_DATA_LENGTH_INFORMATION:
5162                 case SMB_FILE_SHORT_NAME_INFORMATION:
5163                         return NT_STATUS_NOT_SUPPORTED;
5164
5165                 case SMB_FILE_RENAME_INFORMATION:
5166                 {
5167                         status = smb_file_rename_information(conn, req,
5168                                                              pdata, total_data,
5169                                                              fsp, smb_fname);
5170                         break;
5171                 }
5172
5173                 case SMB2_FILE_RENAME_INFORMATION_INTERNAL:
5174                 {
5175                         /* SMB2 rename information. */
5176                         status = smb2_file_rename_information(conn, req,
5177                                                              pdata, total_data,
5178                                                              fsp, smb_fname);
5179                         break;
5180                 }
5181
5182                 case SMB_FILE_LINK_INFORMATION:
5183                 {
5184                         if (conn->sconn->using_smb2) {
5185                                 status = smb2_file_link_information(conn,
5186                                                         req,
5187                                                         pdata,
5188                                                         total_data,
5189                                                         fsp,
5190                                                         smb_fname);
5191                         } else {
5192                                 status = smb_file_link_information(conn,
5193                                                         req,
5194                                                         pdata,
5195                                                         total_data,
5196                                                         fsp,
5197                                                         smb_fname);
5198                         }
5199                         break;
5200                 }
5201
5202                 default:
5203                         return NT_STATUS_INVALID_LEVEL;
5204         }
5205
5206         if (!NT_STATUS_IS_OK(status)) {
5207                 return status;
5208         }
5209
5210         *ret_data_size = data_return_size;
5211         return NT_STATUS_OK;
5212 }
5213
5214 static uint32_t generate_volume_serial_number(
5215                         const struct loadparm_substitution *lp_sub,
5216                         int snum)
5217 {
5218         int serial = lp_volume_serial_number(snum);
5219         return serial != -1 ? serial:
5220                 str_checksum(lp_servicename(talloc_tos(), lp_sub, snum)) ^
5221                 (str_checksum(get_local_machine_name())<<16);
5222 }