smbd: Factor out check_access_fsp() from check_access()
[sfrench/samba-autobuild/.git] / source3 / smbd / trans2.c
1 /*
2    Unix SMB/CIFS implementation.
3    SMB transaction2 handling
4    Copyright (C) Jeremy Allison                 1994-2007
5    Copyright (C) Stefan (metze) Metzmacher      2003
6    Copyright (C) Volker Lendecke                2005-2007
7    Copyright (C) Steve French                   2005
8    Copyright (C) James Peach                    2006-2007
9
10    Extensively modified by Andrew Tridgell, 1995
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 3 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include "includes.h"
27 #include "ntioctl.h"
28 #include "system/filesys.h"
29 #include "version.h"
30 #include "smbd/smbd.h"
31 #include "smbd/globals.h"
32 #include "../libcli/auth/libcli_auth.h"
33 #include "../librpc/gen_ndr/xattr.h"
34 #include "../librpc/gen_ndr/ndr_security.h"
35 #include "../librpc/gen_ndr/open_files.h"
36 #include "libcli/security/security.h"
37 #include "trans2.h"
38 #include "auth.h"
39 #include "smbprofile.h"
40 #include "rpc_server/srv_pipe_hnd.h"
41 #include "printing.h"
42 #include "lib/util_ea.h"
43 #include "lib/readdir_attr.h"
44
45 #define DIR_ENTRY_SAFETY_MARGIN 4096
46
47 static char *store_file_unix_basic(connection_struct *conn,
48                                 char *pdata,
49                                 files_struct *fsp,
50                                 const SMB_STRUCT_STAT *psbuf);
51
52 static char *store_file_unix_basic_info2(connection_struct *conn,
53                                 char *pdata,
54                                 files_struct *fsp,
55                                 const SMB_STRUCT_STAT *psbuf);
56
57 NTSTATUS check_access_fsp(const struct files_struct *fsp,
58                           uint32_t access_mask)
59 {
60         if (!(fsp->access_mask & access_mask)) {
61                 return NT_STATUS_ACCESS_DENIED;
62         }
63         return NT_STATUS_OK;
64 }
65
66 /********************************************************************
67  The canonical "check access" based on object handle or path function.
68 ********************************************************************/
69
70 NTSTATUS check_access(connection_struct *conn,
71                                 files_struct *fsp,
72                                 const struct smb_filename *smb_fname,
73                                 uint32_t access_mask)
74 {
75         if (fsp) {
76                 NTSTATUS status = check_access_fsp(fsp, access_mask);
77                 return status;
78         } else {
79                 NTSTATUS status = smbd_check_access_rights(conn,
80                                         smb_fname,
81                                         false,
82                                         access_mask);
83                 if (!NT_STATUS_IS_OK(status)) {
84                         return status;
85                 }
86                 return NT_STATUS_OK;
87         }
88 }
89
90 /********************************************************************
91  Roundup a value to the nearest allocation roundup size boundary.
92  Only do this for Windows clients.
93 ********************************************************************/
94
95 uint64_t smb_roundup(connection_struct *conn, uint64_t val)
96 {
97         uint64_t rval = lp_allocation_roundup_size(SNUM(conn));
98
99         /* Only roundup for Windows clients. */
100         enum remote_arch_types ra_type = get_remote_arch();
101         if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
102                 val = SMB_ROUNDUP(val,rval);
103         }
104         return val;
105 }
106
107 /********************************************************************
108  Create a 64 bit FileIndex. If the file is on the same device as
109  the root of the share, just return the 64-bit inode. If it isn't,
110  mangle as we used to do.
111 ********************************************************************/
112
113 uint64_t get_FileIndex(connection_struct *conn, const SMB_STRUCT_STAT *psbuf)
114 {
115         uint64_t file_index;
116         if (conn->base_share_dev == psbuf->st_ex_dev) {
117                 return (uint64_t)psbuf->st_ex_ino;
118         }
119         file_index = ((psbuf->st_ex_ino) & UINT32_MAX); /* FileIndexLow */
120         file_index |= ((uint64_t)((psbuf->st_ex_dev) & UINT32_MAX)) << 32; /* FileIndexHigh */
121         return file_index;
122 }
123
124 /****************************************************************************
125  Utility functions for dealing with extended attributes.
126 ****************************************************************************/
127
128 /****************************************************************************
129  Refuse to allow clients to overwrite our private xattrs.
130 ****************************************************************************/
131
132 bool samba_private_attr_name(const char *unix_ea_name)
133 {
134         static const char * const prohibited_ea_names[] = {
135                 SAMBA_POSIX_INHERITANCE_EA_NAME,
136                 SAMBA_XATTR_DOS_ATTRIB,
137                 SAMBA_XATTR_MARKER,
138                 XATTR_NTACL_NAME,
139                 NULL
140         };
141
142         int i;
143
144         for (i = 0; prohibited_ea_names[i]; i++) {
145                 if (strequal( prohibited_ea_names[i], unix_ea_name))
146                         return true;
147         }
148         if (strncasecmp_m(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
149                         strlen(SAMBA_XATTR_DOSSTREAM_PREFIX)) == 0) {
150                 return true;
151         }
152         return false;
153 }
154
155 /****************************************************************************
156  Get one EA value. Fill in a struct ea_struct.
157 ****************************************************************************/
158
159 NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
160                       files_struct *fsp, const char *fname,
161                       const char *ea_name, struct ea_struct *pea)
162 {
163         /* Get the value of this xattr. Max size is 64k. */
164         size_t attr_size = 256;
165         char *val = NULL;
166         ssize_t sizeret;
167
168  again:
169
170         val = talloc_realloc(mem_ctx, val, char, attr_size);
171         if (!val) {
172                 return NT_STATUS_NO_MEMORY;
173         }
174
175         if (fsp && fsp->fh->fd != -1) {
176                 sizeret = SMB_VFS_FGETXATTR(fsp, ea_name, val, attr_size);
177         } else {
178                 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
179         }
180
181         if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
182                 attr_size = 65536;
183                 goto again;
184         }
185
186         if (sizeret == -1) {
187                 return map_nt_error_from_unix(errno);
188         }
189
190         DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name, (unsigned int)sizeret));
191         dump_data(10, (uint8_t *)val, sizeret);
192
193         pea->flags = 0;
194         if (strnequal(ea_name, "user.", 5)) {
195                 pea->name = talloc_strdup(mem_ctx, &ea_name[5]);
196         } else {
197                 pea->name = talloc_strdup(mem_ctx, ea_name);
198         }
199         if (pea->name == NULL) {
200                 TALLOC_FREE(val);
201                 return NT_STATUS_NO_MEMORY;
202         }
203         pea->value.data = (unsigned char *)val;
204         pea->value.length = (size_t)sizeret;
205         return NT_STATUS_OK;
206 }
207
208 NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
209                                 files_struct *fsp, const char *fname,
210                                 char ***pnames, size_t *pnum_names)
211 {
212         /* Get a list of all xattrs. Max namesize is 64k. */
213         size_t ea_namelist_size = 1024;
214         char *ea_namelist = NULL;
215
216         char *p;
217         char **names, **tmp;
218         size_t num_names;
219         ssize_t sizeret = -1;
220
221         if (!lp_ea_support(SNUM(conn))) {
222                 if (pnames) {
223                         *pnames = NULL;
224                 }
225                 *pnum_names = 0;
226                 return NT_STATUS_OK;
227         }
228
229         /*
230          * TALLOC the result early to get the talloc hierarchy right.
231          */
232
233         names = talloc_array(mem_ctx, char *, 1);
234         if (names == NULL) {
235                 DEBUG(0, ("talloc failed\n"));
236                 return NT_STATUS_NO_MEMORY;
237         }
238
239         while (ea_namelist_size <= 65536) {
240
241                 ea_namelist = talloc_realloc(
242                         names, ea_namelist, char, ea_namelist_size);
243                 if (ea_namelist == NULL) {
244                         DEBUG(0, ("talloc failed\n"));
245                         TALLOC_FREE(names);
246                         return NT_STATUS_NO_MEMORY;
247                 }
248
249                 if (fsp && fsp->fh->fd != -1) {
250                         sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
251                                                      ea_namelist_size);
252                 } else {
253                         sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist,
254                                                     ea_namelist_size);
255                 }
256
257                 if ((sizeret == -1) && (errno == ERANGE)) {
258                         ea_namelist_size *= 2;
259                 }
260                 else {
261                         break;
262                 }
263         }
264
265         if (sizeret == -1) {
266                 TALLOC_FREE(names);
267                 return map_nt_error_from_unix(errno);
268         }
269
270         DEBUG(10, ("%s: ea_namelist size = %u\n",
271                    __func__, (unsigned int)sizeret));
272
273         if (sizeret == 0) {
274                 TALLOC_FREE(names);
275                 if (pnames) {
276                         *pnames = NULL;
277                 }
278                 *pnum_names = 0;
279                 return NT_STATUS_OK;
280         }
281
282         /*
283          * Ensure the result is 0-terminated
284          */
285
286         if (ea_namelist[sizeret-1] != '\0') {
287                 TALLOC_FREE(names);
288                 return NT_STATUS_INTERNAL_ERROR;
289         }
290
291         /*
292          * count the names
293          */
294         num_names = 0;
295
296         for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
297                 num_names += 1;
298         }
299
300         tmp = talloc_realloc(mem_ctx, names, char *, num_names);
301         if (tmp == NULL) {
302                 DEBUG(0, ("talloc failed\n"));
303                 TALLOC_FREE(names);
304                 return NT_STATUS_NO_MEMORY;
305         }
306
307         names = tmp;
308         num_names = 0;
309
310         for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
311                 names[num_names++] = p;
312         }
313
314         if (pnames) {
315                 *pnames = names;
316         } else {
317                 TALLOC_FREE(names);
318         }
319         *pnum_names = num_names;
320         return NT_STATUS_OK;
321 }
322
323 /****************************************************************************
324  Return a linked list of the total EA's. Plus the total size
325 ****************************************************************************/
326
327 static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
328                                       const char *fname, size_t *pea_total_len, struct ea_list **ea_list)
329 {
330         /* Get a list of all xattrs. Max namesize is 64k. */
331         size_t i, num_names;
332         char **names;
333         struct ea_list *ea_list_head = NULL;
334         NTSTATUS status;
335
336         *pea_total_len = 0;
337         *ea_list = NULL;
338
339         status = get_ea_names_from_file(talloc_tos(), conn, fsp, fname,
340                                         &names, &num_names);
341
342         if (!NT_STATUS_IS_OK(status)) {
343                 return status;
344         }
345
346         if (num_names == 0) {
347                 *ea_list = NULL;
348                 return NT_STATUS_OK;
349         }
350
351         for (i=0; i<num_names; i++) {
352                 struct ea_list *listp;
353                 fstring dos_ea_name;
354
355                 if (strnequal(names[i], "system.", 7)
356                     || samba_private_attr_name(names[i]))
357                         continue;
358
359                 /*
360                  * Filter out any underlying POSIX EA names
361                  * that a Windows client can't handle.
362                  */
363                 if (!lp_posix_pathnames() &&
364                                 is_invalid_windows_ea_name(names[i])) {
365                         continue;
366                 }
367
368                 listp = talloc(mem_ctx, struct ea_list);
369                 if (listp == NULL) {
370                         return NT_STATUS_NO_MEMORY;
371                 }
372
373                 status = get_ea_value(listp, conn, fsp,
374                                       fname, names[i],
375                                       &listp->ea);
376
377                 if (!NT_STATUS_IS_OK(status)) {
378                         TALLOC_FREE(listp);
379                         return status;
380                 }
381
382                 if (listp->ea.value.length == 0) {
383                         /*
384                          * We can never return a zero length EA.
385                          * Windows reports the EA's as corrupted.
386                          */
387                         TALLOC_FREE(listp);
388                         continue;
389                 }
390
391                 push_ascii_fstring(dos_ea_name, listp->ea.name);
392
393                 *pea_total_len +=
394                         4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
395
396                 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
397                           "= %u\n", (unsigned int)*pea_total_len, dos_ea_name,
398                           (unsigned int)listp->ea.value.length));
399
400                 DLIST_ADD_END(ea_list_head, listp, struct ea_list *);
401
402         }
403
404         /* Add on 4 for total length. */
405         if (*pea_total_len) {
406                 *pea_total_len += 4;
407         }
408
409         DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
410                    (unsigned int)*pea_total_len));
411
412         *ea_list = ea_list_head;
413         return NT_STATUS_OK;
414 }
415
416 static NTSTATUS get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
417                                       const struct smb_filename *smb_fname, size_t *pea_total_len, struct ea_list **ea_list)
418 {
419         *pea_total_len = 0;
420         *ea_list = NULL;
421
422         if (!lp_ea_support(SNUM(conn))) {
423                 return NT_STATUS_OK;
424         }
425
426         if (is_ntfs_stream_smb_fname(smb_fname)) {
427                 return NT_STATUS_INVALID_PARAMETER;
428         }
429
430         return get_ea_list_from_file_path(mem_ctx, conn, fsp, smb_fname->base_name, pea_total_len, ea_list);
431 }
432
433 /****************************************************************************
434  Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
435  that was filled.
436 ****************************************************************************/
437
438 static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
439         connection_struct *conn, struct ea_list *ea_list)
440 {
441         unsigned int ret_data_size = 4;
442         char *p = pdata;
443
444         SMB_ASSERT(total_data_size >= 4);
445
446         if (!lp_ea_support(SNUM(conn))) {
447                 SIVAL(pdata,4,0);
448                 return 4;
449         }
450
451         for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
452                 size_t dos_namelen;
453                 fstring dos_ea_name;
454                 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
455                 dos_namelen = strlen(dos_ea_name);
456                 if (dos_namelen > 255 || dos_namelen == 0) {
457                         break;
458                 }
459                 if (ea_list->ea.value.length > 65535) {
460                         break;
461                 }
462                 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
463                         break;
464                 }
465
466                 /* We know we have room. */
467                 SCVAL(p,0,ea_list->ea.flags);
468                 SCVAL(p,1,dos_namelen);
469                 SSVAL(p,2,ea_list->ea.value.length);
470                 strlcpy(p+4, dos_ea_name, dos_namelen+1);
471                 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
472
473                 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
474                 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
475         }
476
477         ret_data_size = PTR_DIFF(p, pdata);
478         DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
479         SIVAL(pdata,0,ret_data_size);
480         return ret_data_size;
481 }
482
483 static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
484                                        char *pdata,
485                                        unsigned int total_data_size,
486                                        unsigned int *ret_data_size,
487                                        connection_struct *conn,
488                                        struct ea_list *ea_list)
489 {
490         uint8_t *p = (uint8_t *)pdata;
491         uint8_t *last_start = NULL;
492         bool do_store_data = (pdata != NULL);
493
494         *ret_data_size = 0;
495
496         if (!lp_ea_support(SNUM(conn))) {
497                 return NT_STATUS_NO_EAS_ON_FILE;
498         }
499
500         for (; ea_list; ea_list = ea_list->next) {
501                 size_t dos_namelen;
502                 fstring dos_ea_name;
503                 size_t this_size;
504                 size_t pad = 0;
505
506                 if (last_start != NULL && do_store_data) {
507                         SIVAL(last_start, 0, PTR_DIFF(p, last_start));
508                 }
509                 last_start = p;
510
511                 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
512                 dos_namelen = strlen(dos_ea_name);
513                 if (dos_namelen > 255 || dos_namelen == 0) {
514                         return NT_STATUS_INTERNAL_ERROR;
515                 }
516                 if (ea_list->ea.value.length > 65535) {
517                         return NT_STATUS_INTERNAL_ERROR;
518                 }
519
520                 this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length;
521
522                 if (ea_list->next) {
523                         pad = (4 - (this_size % 4)) % 4;
524                         this_size += pad;
525                 }
526
527                 if (do_store_data) {
528                         if (this_size > total_data_size) {
529                                 return NT_STATUS_INFO_LENGTH_MISMATCH;
530                         }
531
532                         /* We know we have room. */
533                         SIVAL(p, 0x00, 0); /* next offset */
534                         SCVAL(p, 0x04, ea_list->ea.flags);
535                         SCVAL(p, 0x05, dos_namelen);
536                         SSVAL(p, 0x06, ea_list->ea.value.length);
537                         strlcpy((char *)(p+0x08), dos_ea_name, dos_namelen+1);
538                         memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
539                         if (pad) {
540                                 memset(p + 0x08 + dos_namelen + 1 + ea_list->ea.value.length,
541                                         '\0',
542                                         pad);
543                         }
544                         total_data_size -= this_size;
545                 }
546
547                 p += this_size;
548         }
549
550         *ret_data_size = PTR_DIFF(p, pdata);
551         DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size));
552         return NT_STATUS_OK;
553 }
554
555 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const struct smb_filename *smb_fname)
556 {
557         size_t total_ea_len = 0;
558         TALLOC_CTX *mem_ctx;
559         struct ea_list *ea_list = NULL;
560
561         if (!lp_ea_support(SNUM(conn))) {
562                 return 0;
563         }
564         mem_ctx = talloc_stackframe();
565
566         /* If this is a stream fsp, then we need to instead find the
567          * estimated ea len from the main file, not the stream
568          * (streams cannot have EAs), but the estimate isn't just 0 in
569          * this case! */
570         if (is_ntfs_stream_smb_fname(smb_fname)) {
571                 fsp = NULL;
572         }
573         (void)get_ea_list_from_file_path(mem_ctx, conn, fsp, smb_fname->base_name, &total_ea_len, &ea_list);
574         if(conn->sconn->using_smb2) {
575                 NTSTATUS status;
576                 unsigned int ret_data_size;
577                 /*
578                  * We're going to be using fill_ea_chained_buffer() to
579                  * marshall EA's - this size is significantly larger
580                  * than the SMB1 buffer. Re-calculate the size without
581                  * marshalling.
582                  */
583                 status = fill_ea_chained_buffer(mem_ctx,
584                                                 NULL,
585                                                 0,
586                                                 &ret_data_size,
587                                                 conn,
588                                                 ea_list);
589                 if (!NT_STATUS_IS_OK(status)) {
590                         ret_data_size = 0;
591                 }
592                 total_ea_len = ret_data_size;
593         }
594         TALLOC_FREE(mem_ctx);
595         return total_ea_len;
596 }
597
598 /****************************************************************************
599  Ensure the EA name is case insensitive by matching any existing EA name.
600 ****************************************************************************/
601
602 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
603 {
604         size_t total_ea_len;
605         TALLOC_CTX *mem_ctx = talloc_tos();
606         struct ea_list *ea_list;
607         NTSTATUS status = get_ea_list_from_file_path(mem_ctx, conn, fsp, fname, &total_ea_len, &ea_list);
608         if (!NT_STATUS_IS_OK(status)) {
609                 return;
610         }
611
612         for (; ea_list; ea_list = ea_list->next) {
613                 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
614                         DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
615                                 &unix_ea_name[5], ea_list->ea.name));
616                         strlcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-5);
617                         break;
618                 }
619         }
620 }
621
622 /****************************************************************************
623  Set or delete an extended attribute.
624 ****************************************************************************/
625
626 NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
627                 const struct smb_filename *smb_fname, struct ea_list *ea_list)
628 {
629         NTSTATUS status;
630         char *fname = NULL;
631
632         if (!lp_ea_support(SNUM(conn))) {
633                 return NT_STATUS_EAS_NOT_SUPPORTED;
634         }
635
636         status = check_access(conn, fsp, smb_fname, FILE_WRITE_EA);
637         if (!NT_STATUS_IS_OK(status)) {
638                 return status;
639         }
640
641         /* Setting EAs on streams isn't supported. */
642         if (is_ntfs_stream_smb_fname(smb_fname)) {
643                 return NT_STATUS_INVALID_PARAMETER;
644         }
645
646         /*
647          * Filter out invalid Windows EA names - before
648          * we set *any* of them.
649          */
650
651         if (ea_list_has_invalid_name(ea_list)) {
652                 return STATUS_INVALID_EA_NAME;
653         }
654
655         fname = smb_fname->base_name;
656
657         for (;ea_list; ea_list = ea_list->next) {
658                 int ret;
659                 fstring unix_ea_name;
660
661                 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
662                 fstrcat(unix_ea_name, ea_list->ea.name);
663
664                 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
665
666                 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
667
668                 if (samba_private_attr_name(unix_ea_name)) {
669                         DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
670                         return NT_STATUS_ACCESS_DENIED;
671                 }
672
673                 if (ea_list->ea.value.length == 0) {
674                         /* Remove the attribute. */
675                         if (fsp && (fsp->fh->fd != -1)) {
676                                 DEBUG(10,("set_ea: deleting ea name %s on "
677                                           "file %s by file descriptor.\n",
678                                           unix_ea_name, fsp_str_dbg(fsp)));
679                                 ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
680                         } else {
681                                 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
682                                         unix_ea_name, fname));
683                                 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
684                         }
685 #ifdef ENOATTR
686                         /* Removing a non existent attribute always succeeds. */
687                         if (ret == -1 && errno == ENOATTR) {
688                                 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
689                                                 unix_ea_name));
690                                 ret = 0;
691                         }
692 #endif
693                 } else {
694                         if (fsp && (fsp->fh->fd != -1)) {
695                                 DEBUG(10,("set_ea: setting ea name %s on file "
696                                           "%s by file descriptor.\n",
697                                           unix_ea_name, fsp_str_dbg(fsp)));
698                                 ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
699                                                         ea_list->ea.value.data, ea_list->ea.value.length, 0);
700                         } else {
701                                 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
702                                         unix_ea_name, fname));
703                                 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
704                                                         ea_list->ea.value.data, ea_list->ea.value.length, 0);
705                         }
706                 }
707
708                 if (ret == -1) {
709 #ifdef ENOTSUP
710                         if (errno == ENOTSUP) {
711                                 return NT_STATUS_EAS_NOT_SUPPORTED;
712                         }
713 #endif
714                         return map_nt_error_from_unix(errno);
715                 }
716
717         }
718         return NT_STATUS_OK;
719 }
720 /****************************************************************************
721  Read a list of EA names from an incoming data buffer. Create an ea_list with them.
722 ****************************************************************************/
723
724 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
725 {
726         struct ea_list *ea_list_head = NULL;
727         size_t converted_size, offset = 0;
728
729         while (offset + 2 < data_size) {
730                 struct ea_list *eal = talloc_zero(ctx, struct ea_list);
731                 unsigned int namelen = CVAL(pdata,offset);
732
733                 offset++; /* Go past the namelen byte. */
734
735                 /* integer wrap paranioa. */
736                 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
737                                 (offset > data_size) || (namelen > data_size) ||
738                                 (offset + namelen >= data_size)) {
739                         break;
740                 }
741                 /* Ensure the name is null terminated. */
742                 if (pdata[offset + namelen] != '\0') {
743                         return NULL;
744                 }
745                 if (!pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset],
746                                        &converted_size)) {
747                         DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
748                                  "failed: %s", strerror(errno)));
749                 }
750                 if (!eal->ea.name) {
751                         return NULL;
752                 }
753
754                 offset += (namelen + 1); /* Go past the name + terminating zero. */
755                 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
756                 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
757         }
758
759         return ea_list_head;
760 }
761
762 /****************************************************************************
763  Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
764 ****************************************************************************/
765
766 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
767 {
768         struct ea_list *ea_list_head = NULL;
769         size_t offset = 0;
770         size_t bytes_used = 0;
771
772         while (offset < data_size) {
773                 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
774
775                 if (!eal) {
776                         return NULL;
777                 }
778
779                 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
780                 offset += bytes_used;
781         }
782
783         return ea_list_head;
784 }
785
786 /****************************************************************************
787  Count the total EA size needed.
788 ****************************************************************************/
789
790 static size_t ea_list_size(struct ea_list *ealist)
791 {
792         fstring dos_ea_name;
793         struct ea_list *listp;
794         size_t ret = 0;
795
796         for (listp = ealist; listp; listp = listp->next) {
797                 push_ascii_fstring(dos_ea_name, listp->ea.name);
798                 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
799         }
800         /* Add on 4 for total length. */
801         if (ret) {
802                 ret += 4;
803         }
804
805         return ret;
806 }
807
808 /****************************************************************************
809  Return a union of EA's from a file list and a list of names.
810  The TALLOC context for the two lists *MUST* be identical as we steal
811  memory from one list to add to another. JRA.
812 ****************************************************************************/
813
814 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
815 {
816         struct ea_list *nlistp, *flistp;
817
818         for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
819                 for (flistp = file_list; flistp; flistp = flistp->next) {
820                         if (strequal(nlistp->ea.name, flistp->ea.name)) {
821                                 break;
822                         }
823                 }
824
825                 if (flistp) {
826                         /* Copy the data from this entry. */
827                         nlistp->ea.flags = flistp->ea.flags;
828                         nlistp->ea.value = flistp->ea.value;
829                 } else {
830                         /* Null entry. */
831                         nlistp->ea.flags = 0;
832                         ZERO_STRUCT(nlistp->ea.value);
833                 }
834         }
835
836         *total_ea_len = ea_list_size(name_list);
837         return name_list;
838 }
839
840 /****************************************************************************
841   Send the required number of replies back.
842   We assume all fields other than the data fields are
843   set correctly for the type of call.
844   HACK ! Always assumes smb_setup field is zero.
845 ****************************************************************************/
846
847 void send_trans2_replies(connection_struct *conn,
848                         struct smb_request *req,
849                         NTSTATUS status,
850                          const char *params,
851                          int paramsize,
852                          const char *pdata,
853                          int datasize,
854                          int max_data_bytes)
855 {
856         /* As we are using a protocol > LANMAN1 then the max_send
857          variable must have been set in the sessetupX call.
858          This takes precedence over the max_xmit field in the
859          global struct. These different max_xmit variables should
860          be merged as this is now too confusing */
861
862         int data_to_send = datasize;
863         int params_to_send = paramsize;
864         int useable_space;
865         const char *pp = params;
866         const char *pd = pdata;
867         int params_sent_thistime, data_sent_thistime, total_sent_thistime;
868         int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
869         int data_alignment_offset = 0;
870         bool overflow = False;
871         struct smbXsrv_connection *xconn = req->xconn;
872         int max_send = xconn->smb1.sessions.max_send;
873
874         /* Modify the data_to_send and datasize and set the error if
875            we're trying to send more than max_data_bytes. We still send
876            the part of the packet(s) that fit. Strange, but needed
877            for OS/2. */
878
879         if (max_data_bytes > 0 && datasize > max_data_bytes) {
880                 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
881                         max_data_bytes, datasize ));
882                 datasize = data_to_send = max_data_bytes;
883                 overflow = True;
884         }
885
886         /* If there genuinely are no parameters or data to send just send the empty packet */
887
888         if(params_to_send == 0 && data_to_send == 0) {
889                 reply_outbuf(req, 10, 0);
890                 if (NT_STATUS_V(status)) {
891                         uint8_t eclass;
892                         uint32_t ecode;
893                         ntstatus_to_dos(status, &eclass, &ecode);
894                         error_packet_set((char *)req->outbuf,
895                                         eclass, ecode, status,
896                                         __LINE__,__FILE__);
897                 }
898                 show_msg((char *)req->outbuf);
899                 if (!srv_send_smb(xconn,
900                                 (char *)req->outbuf,
901                                 true, req->seqnum+1,
902                                 IS_CONN_ENCRYPTED(conn),
903                                 &req->pcd)) {
904                         exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
905                 }
906                 TALLOC_FREE(req->outbuf);
907                 return;
908         }
909
910         /* When sending params and data ensure that both are nicely aligned */
911         /* Only do this alignment when there is also data to send - else
912                 can cause NT redirector problems. */
913
914         if (((params_to_send % 4) != 0) && (data_to_send != 0))
915                 data_alignment_offset = 4 - (params_to_send % 4);
916
917         /* Space is bufsize minus Netbios over TCP header minus SMB header */
918         /* The alignment_offset is to align the param bytes on an even byte
919                 boundary. NT 4.0 Beta needs this to work correctly. */
920
921         useable_space = max_send - (smb_size
922                                     + 2 * 10 /* wct */
923                                     + alignment_offset
924                                     + data_alignment_offset);
925
926         if (useable_space < 0) {
927                 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
928                           "= %d!!!", useable_space));
929                 exit_server_cleanly("send_trans2_replies: Not enough space");
930         }
931
932         while (params_to_send || data_to_send) {
933                 /* Calculate whether we will totally or partially fill this packet */
934
935                 total_sent_thistime = params_to_send + data_to_send;
936
937                 /* We can never send more than useable_space */
938                 /*
939                  * Note that 'useable_space' does not include the alignment offsets,
940                  * but we must include the alignment offsets in the calculation of
941                  * the length of the data we send over the wire, as the alignment offsets
942                  * are sent here. Fix from Marc_Jacobsen@hp.com.
943                  */
944
945                 total_sent_thistime = MIN(total_sent_thistime, useable_space);
946
947                 reply_outbuf(req, 10, total_sent_thistime + alignment_offset
948                              + data_alignment_offset);
949
950                 /* Set total params and data to be sent */
951                 SSVAL(req->outbuf,smb_tprcnt,paramsize);
952                 SSVAL(req->outbuf,smb_tdrcnt,datasize);
953
954                 /* Calculate how many parameters and data we can fit into
955                  * this packet. Parameters get precedence
956                  */
957
958                 params_sent_thistime = MIN(params_to_send,useable_space);
959                 data_sent_thistime = useable_space - params_sent_thistime;
960                 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
961
962                 SSVAL(req->outbuf,smb_prcnt, params_sent_thistime);
963
964                 /* smb_proff is the offset from the start of the SMB header to the
965                         parameter bytes, however the first 4 bytes of outbuf are
966                         the Netbios over TCP header. Thus use smb_base() to subtract
967                         them from the calculation */
968
969                 SSVAL(req->outbuf,smb_proff,
970                       ((smb_buf(req->outbuf)+alignment_offset)
971                        - smb_base(req->outbuf)));
972
973                 if(params_sent_thistime == 0)
974                         SSVAL(req->outbuf,smb_prdisp,0);
975                 else
976                         /* Absolute displacement of param bytes sent in this packet */
977                         SSVAL(req->outbuf,smb_prdisp,pp - params);
978
979                 SSVAL(req->outbuf,smb_drcnt, data_sent_thistime);
980                 if(data_sent_thistime == 0) {
981                         SSVAL(req->outbuf,smb_droff,0);
982                         SSVAL(req->outbuf,smb_drdisp, 0);
983                 } else {
984                         /* The offset of the data bytes is the offset of the
985                                 parameter bytes plus the number of parameters being sent this time */
986                         SSVAL(req->outbuf, smb_droff,
987                               ((smb_buf(req->outbuf)+alignment_offset)
988                                - smb_base(req->outbuf))
989                               + params_sent_thistime + data_alignment_offset);
990                         SSVAL(req->outbuf,smb_drdisp, pd - pdata);
991                 }
992
993                 /* Initialize the padding for alignment */
994
995                 if (alignment_offset != 0) {
996                         memset(smb_buf(req->outbuf), 0, alignment_offset);
997                 }
998
999                 /* Copy the param bytes into the packet */
1000
1001                 if(params_sent_thistime) {
1002                         memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
1003                                params_sent_thistime);
1004                 }
1005
1006                 /* Copy in the data bytes */
1007                 if(data_sent_thistime) {
1008                         if (data_alignment_offset != 0) {
1009                                 memset((smb_buf(req->outbuf)+alignment_offset+
1010                                         params_sent_thistime), 0,
1011                                        data_alignment_offset);
1012                         }
1013                         memcpy(smb_buf(req->outbuf)+alignment_offset
1014                                +params_sent_thistime+data_alignment_offset,
1015                                pd,data_sent_thistime);
1016                 }
1017
1018                 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
1019                         params_sent_thistime, data_sent_thistime, useable_space));
1020                 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
1021                         params_to_send, data_to_send, paramsize, datasize));
1022
1023                 if (overflow) {
1024                         error_packet_set((char *)req->outbuf,
1025                                          ERRDOS,ERRbufferoverflow,
1026                                          STATUS_BUFFER_OVERFLOW,
1027                                          __LINE__,__FILE__);
1028                 } else if (NT_STATUS_V(status)) {
1029                         uint8_t eclass;
1030                         uint32_t ecode;
1031                         ntstatus_to_dos(status, &eclass, &ecode);
1032                         error_packet_set((char *)req->outbuf,
1033                                         eclass, ecode, status,
1034                                         __LINE__,__FILE__);
1035                 }
1036
1037                 /* Send the packet */
1038                 show_msg((char *)req->outbuf);
1039                 if (!srv_send_smb(xconn,
1040                                 (char *)req->outbuf,
1041                                 true, req->seqnum+1,
1042                                 IS_CONN_ENCRYPTED(conn),
1043                                 &req->pcd))
1044                         exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
1045
1046                 TALLOC_FREE(req->outbuf);
1047
1048                 pp += params_sent_thistime;
1049                 pd += data_sent_thistime;
1050
1051                 params_to_send -= params_sent_thistime;
1052                 data_to_send -= data_sent_thistime;
1053
1054                 /* Sanity check */
1055                 if(params_to_send < 0 || data_to_send < 0) {
1056                         DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
1057                                 params_to_send, data_to_send));
1058                         return;
1059                 }
1060         }
1061
1062         return;
1063 }
1064
1065 /****************************************************************************
1066  Reply to a TRANSACT2_OPEN.
1067 ****************************************************************************/
1068
1069 static void call_trans2open(connection_struct *conn,
1070                             struct smb_request *req,
1071                             char **pparams, int total_params,
1072                             char **ppdata, int total_data,
1073                             unsigned int max_data_bytes)
1074 {
1075         struct smb_filename *smb_fname = NULL;
1076         char *params = *pparams;
1077         char *pdata = *ppdata;
1078         int deny_mode;
1079         int32_t open_attr;
1080         bool oplock_request;
1081 #if 0
1082         bool return_additional_info;
1083         int16 open_sattr;
1084         time_t open_time;
1085 #endif
1086         int open_ofun;
1087         uint32_t open_size;
1088         char *pname;
1089         char *fname = NULL;
1090         off_t size=0;
1091         int fattr=0,mtime=0;
1092         SMB_INO_T inode = 0;
1093         int smb_action = 0;
1094         files_struct *fsp;
1095         struct ea_list *ea_list = NULL;
1096         uint16_t flags = 0;
1097         NTSTATUS status;
1098         uint32_t access_mask;
1099         uint32_t share_mode;
1100         uint32_t create_disposition;
1101         uint32_t create_options = 0;
1102         uint32_t private_flags = 0;
1103         TALLOC_CTX *ctx = talloc_tos();
1104
1105         /*
1106          * Ensure we have enough parameters to perform the operation.
1107          */
1108
1109         if (total_params < 29) {
1110                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1111                 goto out;
1112         }
1113
1114         flags = SVAL(params, 0);
1115         deny_mode = SVAL(params, 2);
1116         open_attr = SVAL(params,6);
1117         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
1118         if (oplock_request) {
1119                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
1120         }
1121
1122 #if 0
1123         return_additional_info = BITSETW(params,0);
1124         open_sattr = SVAL(params, 4);
1125         open_time = make_unix_date3(params+8);
1126 #endif
1127         open_ofun = SVAL(params,12);
1128         open_size = IVAL(params,14);
1129         pname = &params[28];
1130
1131         if (IS_IPC(conn)) {
1132                 reply_nterror(req, NT_STATUS_NETWORK_ACCESS_DENIED);
1133                 goto out;
1134         }
1135
1136         srvstr_get_path(ctx, params, req->flags2, &fname, pname,
1137                         total_params - 28, STR_TERMINATE,
1138                         &status);
1139         if (!NT_STATUS_IS_OK(status)) {
1140                 reply_nterror(req, status);
1141                 goto out;
1142         }
1143
1144         DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
1145                 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
1146                 (unsigned int)open_ofun, open_size));
1147
1148         status = filename_convert(ctx,
1149                                 conn,
1150                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
1151                                 fname,
1152                                 0,
1153                                 NULL,
1154                                 &smb_fname);
1155         if (!NT_STATUS_IS_OK(status)) {
1156                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1157                         reply_botherror(req,
1158                                 NT_STATUS_PATH_NOT_COVERED,
1159                                 ERRSRV, ERRbadpath);
1160                         goto out;
1161                 }
1162                 reply_nterror(req, status);
1163                 goto out;
1164         }
1165
1166         if (open_ofun == 0) {
1167                 reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
1168                 goto out;
1169         }
1170
1171         if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
1172                                          open_ofun,
1173                                          &access_mask, &share_mode,
1174                                          &create_disposition,
1175                                          &create_options,
1176                                          &private_flags)) {
1177                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1178                 goto out;
1179         }
1180
1181         /* Any data in this call is an EA list. */
1182         if (total_data && (total_data != 4)) {
1183                 if (total_data < 10) {
1184                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1185                         goto out;
1186                 }
1187
1188                 if (IVAL(pdata,0) > total_data) {
1189                         DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
1190                                 IVAL(pdata,0), (unsigned int)total_data));
1191                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1192                         goto out;
1193                 }
1194
1195                 ea_list = read_ea_list(talloc_tos(), pdata + 4,
1196                                        total_data - 4);
1197                 if (!ea_list) {
1198                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1199                         goto out;
1200                 }
1201
1202                 if (!lp_ea_support(SNUM(conn))) {
1203                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1204                         goto out;
1205                 }
1206
1207                 if (ea_list_has_invalid_name(ea_list)) {
1208                         int param_len = 30;
1209                         *pparams = (char *)SMB_REALLOC(*pparams, param_len);
1210                         if(*pparams == NULL ) {
1211                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
1212                                 goto out;
1213                         }
1214                         params = *pparams;
1215                         memset(params, '\0', param_len);
1216                         send_trans2_replies(conn, req, STATUS_INVALID_EA_NAME,
1217                                 params, param_len, NULL, 0, max_data_bytes);
1218                         goto out;
1219                 }
1220         }
1221
1222         status = SMB_VFS_CREATE_FILE(
1223                 conn,                                   /* conn */
1224                 req,                                    /* req */
1225                 0,                                      /* root_dir_fid */
1226                 smb_fname,                              /* fname */
1227                 access_mask,                            /* access_mask */
1228                 share_mode,                             /* share_access */
1229                 create_disposition,                     /* create_disposition*/
1230                 create_options,                         /* create_options */
1231                 open_attr,                              /* file_attributes */
1232                 oplock_request,                         /* oplock_request */
1233                 NULL,                                   /* lease */
1234                 open_size,                              /* allocation_size */
1235                 private_flags,
1236                 NULL,                                   /* sd */
1237                 ea_list,                                /* ea_list */
1238                 &fsp,                                   /* result */
1239                 &smb_action,                            /* psbuf */
1240                 NULL, NULL);                            /* create context */
1241
1242         if (!NT_STATUS_IS_OK(status)) {
1243                 if (open_was_deferred(req->xconn, req->mid)) {
1244                         /* We have re-scheduled this call. */
1245                         goto out;
1246                 }
1247                 reply_openerror(req, status);
1248                 goto out;
1249         }
1250
1251         size = get_file_size_stat(&smb_fname->st);
1252         fattr = dos_mode(conn, smb_fname);
1253         mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1254         inode = smb_fname->st.st_ex_ino;
1255         if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
1256                 close_file(req, fsp, ERROR_CLOSE);
1257                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1258                 goto out;
1259         }
1260
1261         /* Realloc the size of parameters and data we will return */
1262         *pparams = (char *)SMB_REALLOC(*pparams, 30);
1263         if(*pparams == NULL ) {
1264                 reply_nterror(req, NT_STATUS_NO_MEMORY);
1265                 goto out;
1266         }
1267         params = *pparams;
1268
1269         SSVAL(params,0,fsp->fnum);
1270         SSVAL(params,2,fattr);
1271         srv_put_dos_date2(params,4, mtime);
1272         SIVAL(params,8, (uint32_t)size);
1273         SSVAL(params,12,deny_mode);
1274         SSVAL(params,14,0); /* open_type - file or directory. */
1275         SSVAL(params,16,0); /* open_state - only valid for IPC device. */
1276
1277         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1278                 smb_action |= EXTENDED_OPLOCK_GRANTED;
1279         }
1280
1281         SSVAL(params,18,smb_action);
1282
1283         /*
1284          * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1285          */
1286         SIVAL(params,20,inode);
1287         SSVAL(params,24,0); /* Padding. */
1288         if (flags & 8) {
1289                 uint32_t ea_size = estimate_ea_size(conn, fsp,
1290                                                   smb_fname);
1291                 SIVAL(params, 26, ea_size);
1292         } else {
1293                 SIVAL(params, 26, 0);
1294         }
1295
1296         /* Send the required number of replies */
1297         send_trans2_replies(conn, req, NT_STATUS_OK, params, 30, *ppdata, 0, max_data_bytes);
1298  out:
1299         TALLOC_FREE(smb_fname);
1300 }
1301
1302 /*********************************************************
1303  Routine to check if a given string matches exactly.
1304  as a special case a mask of "." does NOT match. That
1305  is required for correct wildcard semantics
1306  Case can be significant or not.
1307 **********************************************************/
1308
1309 static bool exact_match(bool has_wild,
1310                         bool case_sensitive,
1311                         const char *str,
1312                         const char *mask)
1313 {
1314         if (mask[0] == '.' && mask[1] == 0) {
1315                 return false;
1316         }
1317
1318         if (has_wild) {
1319                 return false;
1320         }
1321
1322         if (case_sensitive) {
1323                 return strcmp(str,mask)==0;
1324         } else {
1325                 return strcasecmp_m(str,mask) == 0;
1326         }
1327 }
1328
1329 /****************************************************************************
1330  Return the filetype for UNIX extensions.
1331 ****************************************************************************/
1332
1333 static uint32_t unix_filetype(mode_t mode)
1334 {
1335         if(S_ISREG(mode))
1336                 return UNIX_TYPE_FILE;
1337         else if(S_ISDIR(mode))
1338                 return UNIX_TYPE_DIR;
1339 #ifdef S_ISLNK
1340         else if(S_ISLNK(mode))
1341                 return UNIX_TYPE_SYMLINK;
1342 #endif
1343 #ifdef S_ISCHR
1344         else if(S_ISCHR(mode))
1345                 return UNIX_TYPE_CHARDEV;
1346 #endif
1347 #ifdef S_ISBLK
1348         else if(S_ISBLK(mode))
1349                 return UNIX_TYPE_BLKDEV;
1350 #endif
1351 #ifdef S_ISFIFO
1352         else if(S_ISFIFO(mode))
1353                 return UNIX_TYPE_FIFO;
1354 #endif
1355 #ifdef S_ISSOCK
1356         else if(S_ISSOCK(mode))
1357                 return UNIX_TYPE_SOCKET;
1358 #endif
1359
1360         DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
1361         return UNIX_TYPE_UNKNOWN;
1362 }
1363
1364 /****************************************************************************
1365  Map wire perms onto standard UNIX permissions. Obey share restrictions.
1366 ****************************************************************************/
1367
1368 enum perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR};
1369
1370 static NTSTATUS unix_perms_from_wire( connection_struct *conn,
1371                                 const SMB_STRUCT_STAT *psbuf,
1372                                 uint32_t perms,
1373                                 enum perm_type ptype,
1374                                 mode_t *ret_perms)
1375 {
1376         mode_t ret = 0;
1377
1378         if (perms == SMB_MODE_NO_CHANGE) {
1379                 if (!VALID_STAT(*psbuf)) {
1380                         return NT_STATUS_INVALID_PARAMETER;
1381                 } else {
1382                         *ret_perms = psbuf->st_ex_mode;
1383                         return NT_STATUS_OK;
1384                 }
1385         }
1386
1387         ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
1388         ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
1389         ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
1390         ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
1391         ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
1392         ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
1393         ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
1394         ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
1395         ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
1396 #ifdef S_ISVTX
1397         ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
1398 #endif
1399 #ifdef S_ISGID
1400         ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
1401 #endif
1402 #ifdef S_ISUID
1403         ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
1404 #endif
1405
1406         if (ptype == PERM_NEW_FILE) {
1407                 /*
1408                  * "create mask"/"force create mode" are
1409                  * only applied to new files, not existing ones.
1410                  */
1411                 ret &= lp_create_mask(SNUM(conn));
1412                 /* Add in force bits */
1413                 ret |= lp_force_create_mode(SNUM(conn));
1414         } else if (ptype == PERM_NEW_DIR) {
1415                 /*
1416                  * "directory mask"/"force directory mode" are
1417                  * only applied to new directories, not existing ones.
1418                  */
1419                 ret &= lp_directory_mask(SNUM(conn));
1420                 /* Add in force bits */
1421                 ret |= lp_force_directory_mode(SNUM(conn));
1422         }
1423
1424         *ret_perms = ret;
1425         return NT_STATUS_OK;
1426 }
1427
1428 /****************************************************************************
1429  Needed to show the msdfs symlinks as directories. Modifies psbuf
1430  to be a directory if it's a msdfs link.
1431 ****************************************************************************/
1432
1433 static bool check_msdfs_link(connection_struct *conn,
1434                                 const char *pathname,
1435                                 SMB_STRUCT_STAT *psbuf)
1436 {
1437         int saved_errno = errno;
1438         if(lp_host_msdfs() &&
1439                 lp_msdfs_root(SNUM(conn)) &&
1440                 is_msdfs_link(conn, pathname, psbuf)) {
1441
1442                 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1443                         "as a directory\n",
1444                         pathname));
1445                 psbuf->st_ex_mode = (psbuf->st_ex_mode & 0xFFF) | S_IFDIR;
1446                 errno = saved_errno;
1447                 return true;
1448         }
1449         errno = saved_errno;
1450         return false;
1451 }
1452
1453
1454 /****************************************************************************
1455  Get a level dependent lanman2 dir entry.
1456 ****************************************************************************/
1457
1458 struct smbd_dirptr_lanman2_state {
1459         connection_struct *conn;
1460         uint32_t info_level;
1461         bool check_mangled_names;
1462         bool has_wild;
1463         bool got_exact_match;
1464 };
1465
1466 static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX *ctx,
1467                                          void *private_data,
1468                                          const char *dname,
1469                                          const char *mask,
1470                                          char **_fname)
1471 {
1472         struct smbd_dirptr_lanman2_state *state =
1473                 (struct smbd_dirptr_lanman2_state *)private_data;
1474         bool ok;
1475         char mangled_name[13]; /* mangled 8.3 name. */
1476         bool got_match;
1477         const char *fname;
1478
1479         /* Mangle fname if it's an illegal name. */
1480         if (mangle_must_mangle(dname, state->conn->params)) {
1481                 /*
1482                  * Slow path - ensure we can push the original name as UCS2. If
1483                  * not, then just don't return this name.
1484                  */
1485                 NTSTATUS status;
1486                 size_t ret_len = 0;
1487                 size_t len = (strlen(dname) + 2) * 4; /* Allow enough space. */
1488                 uint8_t *tmp = talloc_array(talloc_tos(),
1489                                         uint8_t,
1490                                         len);
1491
1492                 status = srvstr_push(NULL,
1493                         FLAGS2_UNICODE_STRINGS,
1494                         tmp,
1495                         dname,
1496                         len,
1497                         STR_TERMINATE,
1498                         &ret_len);
1499
1500                 TALLOC_FREE(tmp);
1501
1502                 if (!NT_STATUS_IS_OK(status)) {
1503                         return false;
1504                 }
1505
1506                 ok = name_to_8_3(dname, mangled_name,
1507                                  true, state->conn->params);
1508                 if (!ok) {
1509                         return false;
1510                 }
1511                 fname = mangled_name;
1512         } else {
1513                 fname = dname;
1514         }
1515
1516         got_match = exact_match(state->has_wild,
1517                                 state->conn->case_sensitive,
1518                                 fname, mask);
1519         state->got_exact_match = got_match;
1520         if (!got_match) {
1521                 got_match = mask_match(fname, mask,
1522                                        state->conn->case_sensitive);
1523         }
1524
1525         if(!got_match && state->check_mangled_names &&
1526            !mangle_is_8_3(fname, false, state->conn->params)) {
1527                 /*
1528                  * It turns out that NT matches wildcards against
1529                  * both long *and* short names. This may explain some
1530                  * of the wildcard wierdness from old DOS clients
1531                  * that some people have been seeing.... JRA.
1532                  */
1533                 /* Force the mangling into 8.3. */
1534                 ok = name_to_8_3(fname, mangled_name,
1535                                  false, state->conn->params);
1536                 if (!ok) {
1537                         return false;
1538                 }
1539
1540                 got_match = exact_match(state->has_wild,
1541                                         state->conn->case_sensitive,
1542                                         mangled_name, mask);
1543                 state->got_exact_match = got_match;
1544                 if (!got_match) {
1545                         got_match = mask_match(mangled_name, mask,
1546                                                state->conn->case_sensitive);
1547                 }
1548         }
1549
1550         if (!got_match) {
1551                 return false;
1552         }
1553
1554         *_fname = talloc_strdup(ctx, fname);
1555         if (*_fname == NULL) {
1556                 return false;
1557         }
1558
1559         return true;
1560 }
1561
1562 static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX *ctx,
1563                                         void *private_data,
1564                                         struct smb_filename *smb_fname,
1565                                         uint32_t *_mode)
1566 {
1567         struct smbd_dirptr_lanman2_state *state =
1568                 (struct smbd_dirptr_lanman2_state *)private_data;
1569         bool ms_dfs_link = false;
1570         uint32_t mode = 0;
1571
1572         if (INFO_LEVEL_IS_UNIX(state->info_level)) {
1573                 if (SMB_VFS_LSTAT(state->conn, smb_fname) != 0) {
1574                         DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1575                                  "Couldn't lstat [%s] (%s)\n",
1576                                  smb_fname_str_dbg(smb_fname),
1577                                  strerror(errno)));
1578                         return false;
1579                 }
1580         } else if (!VALID_STAT(smb_fname->st) &&
1581                    SMB_VFS_STAT(state->conn, smb_fname) != 0) {
1582                 /* Needed to show the msdfs symlinks as
1583                  * directories */
1584
1585                 ms_dfs_link = check_msdfs_link(state->conn,
1586                                                smb_fname->base_name,
1587                                                &smb_fname->st);
1588                 if (!ms_dfs_link) {
1589                         DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1590                                  "Couldn't stat [%s] (%s)\n",
1591                                  smb_fname_str_dbg(smb_fname),
1592                                  strerror(errno)));
1593                         return false;
1594                 }
1595         }
1596
1597         if (ms_dfs_link) {
1598                 mode = dos_mode_msdfs(state->conn, smb_fname);
1599         } else {
1600                 mode = dos_mode(state->conn, smb_fname);
1601         }
1602
1603         *_mode = mode;
1604         return true;
1605 }
1606
1607 static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
1608                                     connection_struct *conn,
1609                                     uint16_t flags2,
1610                                     uint32_t info_level,
1611                                     struct ea_list *name_list,
1612                                     bool check_mangled_names,
1613                                     bool requires_resume_key,
1614                                     uint32_t mode,
1615                                     const char *fname,
1616                                     const struct smb_filename *smb_fname,
1617                                     int space_remaining,
1618                                     uint8_t align,
1619                                     bool do_pad,
1620                                     char *base_data,
1621                                     char **ppdata,
1622                                     char *end_data,
1623                                     uint64_t *last_entry_off)
1624 {
1625         char *p, *q, *pdata = *ppdata;
1626         uint32_t reskey=0;
1627         uint64_t file_size = 0;
1628         uint64_t allocation_size = 0;
1629         uint64_t file_index = 0;
1630         size_t len = 0;
1631         struct timespec mdate_ts = {0};
1632         struct timespec adate_ts = {0};
1633         struct timespec cdate_ts = {0};
1634         struct timespec create_date_ts = {0};
1635         time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1636         char *nameptr;
1637         char *last_entry_ptr;
1638         bool was_8_3;
1639         int off;
1640         int pad = 0;
1641         NTSTATUS status;
1642         struct readdir_attr_data *readdir_attr_data = NULL;
1643
1644         if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
1645                 file_size = get_file_size_stat(&smb_fname->st);
1646         }
1647         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
1648
1649         status = SMB_VFS_READDIR_ATTR(conn, smb_fname, ctx, &readdir_attr_data);
1650         if (!NT_STATUS_IS_OK(status)) {
1651                 if (!NT_STATUS_EQUAL(NT_STATUS_NOT_SUPPORTED, status)) {
1652                         return status;
1653                 }
1654         }
1655
1656         file_index = get_FileIndex(conn, &smb_fname->st);
1657
1658         mdate_ts = smb_fname->st.st_ex_mtime;
1659         adate_ts = smb_fname->st.st_ex_atime;
1660         create_date_ts = get_create_timespec(conn, NULL, smb_fname);
1661         cdate_ts = get_change_timespec(conn, NULL, smb_fname);
1662
1663         if (lp_dos_filetime_resolution(SNUM(conn))) {
1664                 dos_filetime_timespec(&create_date_ts);
1665                 dos_filetime_timespec(&mdate_ts);
1666                 dos_filetime_timespec(&adate_ts);
1667                 dos_filetime_timespec(&cdate_ts);
1668         }
1669
1670         create_date = convert_timespec_to_time_t(create_date_ts);
1671         mdate = convert_timespec_to_time_t(mdate_ts);
1672         adate = convert_timespec_to_time_t(adate_ts);
1673
1674         /* align the record */
1675         SMB_ASSERT(align >= 1);
1676
1677         off = (int)PTR_DIFF(pdata, base_data);
1678         pad = (off + (align-1)) & ~(align-1);
1679         pad -= off;
1680
1681         if (pad && pad > space_remaining) {
1682                 DEBUG(9,("smbd_marshall_dir_entry: out of space "
1683                         "for padding (wanted %u, had %d)\n",
1684                         (unsigned int)pad,
1685                         space_remaining ));
1686                 return STATUS_MORE_ENTRIES; /* Not finished - just out of space */
1687         }
1688
1689         off += pad;
1690         /* initialize padding to 0 */
1691         if (pad) {
1692                 memset(pdata, 0, pad);
1693         }
1694         space_remaining -= pad;
1695
1696         DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
1697                 space_remaining ));
1698
1699         pdata += pad;
1700         p = pdata;
1701         last_entry_ptr = p;
1702
1703         pad = 0;
1704         off = 0;
1705
1706         switch (info_level) {
1707         case SMB_FIND_INFO_STANDARD:
1708                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1709                 if(requires_resume_key) {
1710                         SIVAL(p,0,reskey);
1711                         p += 4;
1712                 }
1713                 srv_put_dos_date2(p,0,create_date);
1714                 srv_put_dos_date2(p,4,adate);
1715                 srv_put_dos_date2(p,8,mdate);
1716                 SIVAL(p,12,(uint32_t)file_size);
1717                 SIVAL(p,16,(uint32_t)allocation_size);
1718                 SSVAL(p,20,mode);
1719                 p += 23;
1720                 nameptr = p;
1721                 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1722                         p += ucs2_align(base_data, p, 0);
1723                 }
1724                 status = srvstr_push(base_data, flags2, p,
1725                                   fname, PTR_DIFF(end_data, p),
1726                                   STR_TERMINATE, &len);
1727                 if (!NT_STATUS_IS_OK(status)) {
1728                         return status;
1729                 }
1730                 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1731                         if (len > 2) {
1732                                 SCVAL(nameptr, -1, len - 2);
1733                         } else {
1734                                 SCVAL(nameptr, -1, 0);
1735                         }
1736                 } else {
1737                         if (len > 1) {
1738                                 SCVAL(nameptr, -1, len - 1);
1739                         } else {
1740                                 SCVAL(nameptr, -1, 0);
1741                         }
1742                 }
1743                 p += len;
1744                 break;
1745
1746         case SMB_FIND_EA_SIZE:
1747                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
1748                 if (requires_resume_key) {
1749                         SIVAL(p,0,reskey);
1750                         p += 4;
1751                 }
1752                 srv_put_dos_date2(p,0,create_date);
1753                 srv_put_dos_date2(p,4,adate);
1754                 srv_put_dos_date2(p,8,mdate);
1755                 SIVAL(p,12,(uint32_t)file_size);
1756                 SIVAL(p,16,(uint32_t)allocation_size);
1757                 SSVAL(p,20,mode);
1758                 {
1759                         unsigned int ea_size = estimate_ea_size(conn, NULL,
1760                                                                 smb_fname);
1761                         SIVAL(p,22,ea_size); /* Extended attributes */
1762                 }
1763                 p += 27;
1764                 nameptr = p - 1;
1765                 status = srvstr_push(base_data, flags2,
1766                                   p, fname, PTR_DIFF(end_data, p),
1767                                   STR_TERMINATE | STR_NOALIGN, &len);
1768                 if (!NT_STATUS_IS_OK(status)) {
1769                         return status;
1770                 }
1771                 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1772                         if (len > 2) {
1773                                 len -= 2;
1774                         } else {
1775                                 len = 0;
1776                         }
1777                 } else {
1778                         if (len > 1) {
1779                                 len -= 1;
1780                         } else {
1781                                 len = 0;
1782                         }
1783                 }
1784                 SCVAL(nameptr,0,len);
1785                 p += len;
1786                 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1787                 break;
1788
1789         case SMB_FIND_EA_LIST:
1790         {
1791                 struct ea_list *file_list = NULL;
1792                 size_t ea_len = 0;
1793
1794                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
1795                 if (!name_list) {
1796                         return NT_STATUS_INVALID_PARAMETER;
1797                 }
1798                 if (requires_resume_key) {
1799                         SIVAL(p,0,reskey);
1800                         p += 4;
1801                 }
1802                 srv_put_dos_date2(p,0,create_date);
1803                 srv_put_dos_date2(p,4,adate);
1804                 srv_put_dos_date2(p,8,mdate);
1805                 SIVAL(p,12,(uint32_t)file_size);
1806                 SIVAL(p,16,(uint32_t)allocation_size);
1807                 SSVAL(p,20,mode);
1808                 p += 22; /* p now points to the EA area. */
1809
1810                 status = get_ea_list_from_file(ctx, conn, NULL,
1811                                                smb_fname,
1812                                                &ea_len, &file_list);
1813                 if (!NT_STATUS_IS_OK(status)) {
1814                         file_list = NULL;
1815                 }
1816                 name_list = ea_list_union(name_list, file_list, &ea_len);
1817
1818                 /* We need to determine if this entry will fit in the space available. */
1819                 /* Max string size is 255 bytes. */
1820                 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1821                         DEBUG(9,("smbd_marshall_dir_entry: out of space "
1822                                 "(wanted %u, had %d)\n",
1823                                 (unsigned int)PTR_DIFF(p + 255 + ea_len,pdata),
1824                                 space_remaining ));
1825                         return STATUS_MORE_ENTRIES; /* Not finished - just out of space */
1826                 }
1827
1828                 /* Push the ea_data followed by the name. */
1829                 p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
1830                 nameptr = p;
1831                 status = srvstr_push(base_data, flags2,
1832                                   p + 1, fname, PTR_DIFF(end_data, p+1),
1833                                   STR_TERMINATE | STR_NOALIGN, &len);
1834                 if (!NT_STATUS_IS_OK(status)) {
1835                         return status;
1836                 }
1837                 if (flags2 & FLAGS2_UNICODE_STRINGS) {
1838                         if (len > 2) {
1839                                 len -= 2;
1840                         } else {
1841                                 len = 0;
1842                         }
1843                 } else {
1844                         if (len > 1) {
1845                                 len -= 1;
1846                         } else {
1847                                 len = 0;
1848                         }
1849                 }
1850                 SCVAL(nameptr,0,len);
1851                 p += len + 1;
1852                 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1853                 break;
1854         }
1855
1856         case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1857                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1858                 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1859                 p += 4;
1860                 SIVAL(p,0,reskey); p += 4;
1861                 put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
1862                 put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
1863                 put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
1864                 put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
1865                 SOFF_T(p,0,file_size); p += 8;
1866                 SOFF_T(p,0,allocation_size); p += 8;
1867                 SIVAL(p,0,mode); p += 4;
1868                 q = p; p += 4; /* q is placeholder for name length. */
1869                 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
1870                         SIVAL(p, 0, IO_REPARSE_TAG_DFS);
1871                 } else {
1872                         unsigned int ea_size = estimate_ea_size(conn, NULL,
1873                                                                 smb_fname);
1874                         SIVAL(p,0,ea_size); /* Extended attributes */
1875                 }
1876                 p += 4;
1877                 /* Clear the short name buffer. This is
1878                  * IMPORTANT as not doing so will trigger
1879                  * a Win2k client bug. JRA.
1880                  */
1881                 if (!was_8_3 && check_mangled_names) {
1882                         char mangled_name[13]; /* mangled 8.3 name. */
1883                         if (!name_to_8_3(fname,mangled_name,True,
1884                                            conn->params)) {
1885                                 /* Error - mangle failed ! */
1886                                 memset(mangled_name,'\0',12);
1887                         }
1888                         mangled_name[12] = 0;
1889                         status = srvstr_push(base_data, flags2,
1890                                           p+2, mangled_name, 24,
1891                                           STR_UPPER|STR_UNICODE, &len);
1892                         if (!NT_STATUS_IS_OK(status)) {
1893                                 return status;
1894                         }
1895                         if (len < 24) {
1896                                 memset(p + 2 + len,'\0',24 - len);
1897                         }
1898                         SSVAL(p, 0, len);
1899                 } else {
1900                         memset(p,'\0',26);
1901                 }
1902                 p += 2 + 24;
1903                 status = srvstr_push(base_data, flags2, p,
1904                                   fname, PTR_DIFF(end_data, p),
1905                                   STR_TERMINATE_ASCII, &len);
1906                 if (!NT_STATUS_IS_OK(status)) {
1907                         return status;
1908                 }
1909                 SIVAL(q,0,len);
1910                 p += len;
1911
1912                 len = PTR_DIFF(p, pdata);
1913                 pad = (len + (align-1)) & ~(align-1);
1914                 /*
1915                  * offset to the next entry, the caller
1916                  * will overwrite it for the last entry
1917                  * that's why we always include the padding
1918                  */
1919                 SIVAL(pdata,0,pad);
1920                 /*
1921                  * set padding to zero
1922                  */
1923                 if (do_pad) {
1924                         memset(p, 0, pad - len);
1925                         p = pdata + pad;
1926                 } else {
1927                         p = pdata + len;
1928                 }
1929                 break;
1930
1931         case SMB_FIND_FILE_DIRECTORY_INFO:
1932                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1933                 p += 4;
1934                 SIVAL(p,0,reskey); p += 4;
1935                 put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
1936                 put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
1937                 put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
1938                 put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
1939                 SOFF_T(p,0,file_size); p += 8;
1940                 SOFF_T(p,0,allocation_size); p += 8;
1941                 SIVAL(p,0,mode); p += 4;
1942                 status = srvstr_push(base_data, flags2,
1943                                   p + 4, fname, PTR_DIFF(end_data, p+4),
1944                                   STR_TERMINATE_ASCII, &len);
1945                 if (!NT_STATUS_IS_OK(status)) {
1946                         return status;
1947                 }
1948                 SIVAL(p,0,len);
1949                 p += 4 + len;
1950
1951                 len = PTR_DIFF(p, pdata);
1952                 pad = (len + (align-1)) & ~(align-1);
1953                 /*
1954                  * offset to the next entry, the caller
1955                  * will overwrite it for the last entry
1956                  * that's why we always include the padding
1957                  */
1958                 SIVAL(pdata,0,pad);
1959                 /*
1960                  * set padding to zero
1961                  */
1962                 if (do_pad) {
1963                         memset(p, 0, pad - len);
1964                         p = pdata + pad;
1965                 } else {
1966                         p = pdata + len;
1967                 }
1968                 break;
1969
1970         case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1971                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1972                 p += 4;
1973                 SIVAL(p,0,reskey); p += 4;
1974                 put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
1975                 put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
1976                 put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
1977                 put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
1978                 SOFF_T(p,0,file_size); p += 8;
1979                 SOFF_T(p,0,allocation_size); p += 8;
1980                 SIVAL(p,0,mode); p += 4;
1981                 q = p; p += 4; /* q is placeholder for name length. */
1982                 {
1983                         unsigned int ea_size = estimate_ea_size(conn, NULL,
1984                                                                 smb_fname);
1985                         SIVAL(p,0,ea_size); /* Extended attributes */
1986                         p +=4;
1987                 }
1988                 status = srvstr_push(base_data, flags2, p,
1989                                   fname, PTR_DIFF(end_data, p),
1990                                   STR_TERMINATE_ASCII, &len);
1991                 if (!NT_STATUS_IS_OK(status)) {
1992                         return status;
1993                 }
1994                 SIVAL(q, 0, len);
1995                 p += len;
1996
1997                 len = PTR_DIFF(p, pdata);
1998                 pad = (len + (align-1)) & ~(align-1);
1999                 /*
2000                  * offset to the next entry, the caller
2001                  * will overwrite it for the last entry
2002                  * that's why we always include the padding
2003                  */
2004                 SIVAL(pdata,0,pad);
2005                 /*
2006                  * set padding to zero
2007                  */
2008                 if (do_pad) {
2009                         memset(p, 0, pad - len);
2010                         p = pdata + pad;
2011                 } else {
2012                         p = pdata + len;
2013                 }
2014                 break;
2015
2016         case SMB_FIND_FILE_NAMES_INFO:
2017                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
2018                 p += 4;
2019                 SIVAL(p,0,reskey); p += 4;
2020                 p += 4;
2021                 /* this must *not* be null terminated or w2k gets in a loop trying to set an
2022                    acl on a dir (tridge) */
2023                 status = srvstr_push(base_data, flags2, p,
2024                                   fname, PTR_DIFF(end_data, p),
2025                                   STR_TERMINATE_ASCII, &len);
2026                 if (!NT_STATUS_IS_OK(status)) {
2027                         return status;
2028                 }
2029                 SIVAL(p, -4, len);
2030                 p += len;
2031
2032                 len = PTR_DIFF(p, pdata);
2033                 pad = (len + (align-1)) & ~(align-1);
2034                 /*
2035                  * offset to the next entry, the caller
2036                  * will overwrite it for the last entry
2037                  * that's why we always include the padding
2038                  */
2039                 SIVAL(pdata,0,pad);
2040                 /*
2041                  * set padding to zero
2042                  */
2043                 if (do_pad) {
2044                         memset(p, 0, pad - len);
2045                         p = pdata + pad;
2046                 } else {
2047                         p = pdata + len;
2048                 }
2049                 break;
2050
2051         case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2052                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
2053                 p += 4;
2054                 SIVAL(p,0,reskey); p += 4;
2055                 put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
2056                 put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
2057                 put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
2058                 put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
2059                 SOFF_T(p,0,file_size); p += 8;
2060                 SOFF_T(p,0,allocation_size); p += 8;
2061                 SIVAL(p,0,mode); p += 4;
2062                 q = p; p += 4; /* q is placeholder for name length. */
2063                 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
2064                         SIVAL(p, 0, IO_REPARSE_TAG_DFS);
2065                 } else {
2066                         unsigned int ea_size = estimate_ea_size(conn, NULL,
2067                                                                 smb_fname);
2068                         SIVAL(p,0,ea_size); /* Extended attributes */
2069                 }
2070                 p += 4;
2071                 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
2072                 SBVAL(p,0,file_index); p += 8;
2073                 status = srvstr_push(base_data, flags2, p,
2074                                   fname, PTR_DIFF(end_data, p),
2075                                   STR_TERMINATE_ASCII, &len);
2076                 if (!NT_STATUS_IS_OK(status)) {
2077                         return status;
2078                 }
2079                 SIVAL(q, 0, len);
2080                 p += len;
2081
2082                 len = PTR_DIFF(p, pdata);
2083                 pad = (len + (align-1)) & ~(align-1);
2084                 /*
2085                  * offset to the next entry, the caller
2086                  * will overwrite it for the last entry
2087                  * that's why we always include the padding
2088                  */
2089                 SIVAL(pdata,0,pad);
2090                 /*
2091                  * set padding to zero
2092                  */
2093                 if (do_pad) {
2094                         memset(p, 0, pad - len);
2095                         p = pdata + pad;
2096                 } else {
2097                         p = pdata + len;
2098                 }
2099                 break;
2100
2101         case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2102                 DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
2103                 was_8_3 = mangle_is_8_3(fname, True, conn->params);
2104                 p += 4;
2105                 SIVAL(p,0,reskey); p += 4;
2106                 put_long_date_timespec(conn->ts_res,p,create_date_ts); p += 8;
2107                 put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
2108                 put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
2109                 put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
2110                 SOFF_T(p,0,file_size); p += 8;
2111                 SOFF_T(p,0,allocation_size); p += 8;
2112                 SIVAL(p,0,mode); p += 4;
2113                 q = p; p += 4; /* q is placeholder for name length */
2114                 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
2115                         SIVAL(p, 0, IO_REPARSE_TAG_DFS);
2116                 } else if (readdir_attr_data &&
2117                            readdir_attr_data->type == RDATTR_AAPL) {
2118                         /*
2119                          * OS X specific SMB2 extension negotiated via
2120                          * AAPL create context: return max_access in
2121                          * ea_size field.
2122                          */
2123                         SIVAL(p, 0, readdir_attr_data->attr_data.aapl.max_access);
2124                 } else {
2125                         unsigned int ea_size = estimate_ea_size(conn, NULL,
2126                                                                 smb_fname);
2127                         SIVAL(p,0,ea_size); /* Extended attributes */
2128                 }
2129                 p += 4;
2130
2131                 if (readdir_attr_data &&
2132                     readdir_attr_data->type == RDATTR_AAPL) {
2133                         /*
2134                          * OS X specific SMB2 extension negotiated via
2135                          * AAPL create context: return resource fork
2136                          * length and compressed FinderInfo in
2137                          * shortname field.
2138                          *
2139                          * According to documentation short_name_len
2140                          * should be 0, but on the wire behaviour
2141                          * shows its set to 24 by clients.
2142                          */
2143                         SSVAL(p, 0, 24);
2144
2145                         /* Resourefork length */
2146                         SBVAL(p, 2, readdir_attr_data->attr_data.aapl.rfork_size);
2147
2148                         /* Compressed FinderInfo */
2149                         memcpy(p + 10, &readdir_attr_data->attr_data.aapl.finder_info, 16);
2150                 } else if (!was_8_3 && check_mangled_names) {
2151                         char mangled_name[13]; /* mangled 8.3 name. */
2152                         if (!name_to_8_3(fname,mangled_name,True,
2153                                         conn->params)) {
2154                                 /* Error - mangle failed ! */
2155                                 memset(mangled_name,'\0',12);
2156                         }
2157                         mangled_name[12] = 0;
2158                         status = srvstr_push(base_data, flags2,
2159                                           p+2, mangled_name, 24,
2160                                           STR_UPPER|STR_UNICODE, &len);
2161                         if (!NT_STATUS_IS_OK(status)) {
2162                                 return status;
2163                         }
2164                         SSVAL(p, 0, len);
2165                         if (len < 24) {
2166                                 memset(p + 2 + len,'\0',24 - len);
2167                         }
2168                         SSVAL(p, 0, len);
2169                 } else {
2170                         /* Clear the short name buffer. This is
2171                          * IMPORTANT as not doing so will trigger
2172                          * a Win2k client bug. JRA.
2173                          */
2174                         memset(p,'\0',26);
2175                 }
2176                 p += 26;
2177
2178                 /* Reserved ? */
2179                 if (readdir_attr_data &&
2180                     readdir_attr_data->type == RDATTR_AAPL) {
2181                         /*
2182                          * OS X specific SMB2 extension negotiated via
2183                          * AAPL create context: return UNIX mode in
2184                          * reserved field.
2185                          */
2186                         uint16_t aapl_mode = (uint16_t)readdir_attr_data->attr_data.aapl.unix_mode;
2187                         SSVAL(p, 0, aapl_mode);
2188                 } else {
2189                         SSVAL(p, 0, 0);
2190                 }
2191                 p += 2;
2192
2193                 SBVAL(p,0,file_index); p += 8;
2194                 status = srvstr_push(base_data, flags2, p,
2195                                   fname, PTR_DIFF(end_data, p),
2196                                   STR_TERMINATE_ASCII, &len);
2197                 if (!NT_STATUS_IS_OK(status)) {
2198                         return status;
2199                 }
2200                 SIVAL(q,0,len);
2201                 p += len;
2202
2203                 len = PTR_DIFF(p, pdata);
2204                 pad = (len + (align-1)) & ~(align-1);
2205                 /*
2206                  * offset to the next entry, the caller
2207                  * will overwrite it for the last entry
2208                  * that's why we always include the padding
2209                  */
2210                 SIVAL(pdata,0,pad);
2211                 /*
2212                  * set padding to zero
2213                  */
2214                 if (do_pad) {
2215                         memset(p, 0, pad - len);
2216                         p = pdata + pad;
2217                 } else {
2218                         p = pdata + len;
2219                 }
2220                 break;
2221
2222         /* CIFS UNIX Extension. */
2223
2224         case SMB_FIND_FILE_UNIX:
2225         case SMB_FIND_FILE_UNIX_INFO2:
2226                 p+= 4;
2227                 SIVAL(p,0,reskey); p+= 4;    /* Used for continuing search. */
2228
2229                 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
2230
2231                 if (info_level == SMB_FIND_FILE_UNIX) {
2232                         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
2233                         p = store_file_unix_basic(conn, p,
2234                                                 NULL, &smb_fname->st);
2235                         status = srvstr_push(base_data, flags2, p,
2236                                           fname, PTR_DIFF(end_data, p),
2237                                           STR_TERMINATE, &len);
2238                         if (!NT_STATUS_IS_OK(status)) {
2239                                 return status;
2240                         }
2241                 } else {
2242                         DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
2243                         p = store_file_unix_basic_info2(conn, p,
2244                                                 NULL, &smb_fname->st);
2245                         nameptr = p;
2246                         p += 4;
2247                         status = srvstr_push(base_data, flags2, p, fname,
2248                                           PTR_DIFF(end_data, p), 0, &len);
2249                         if (!NT_STATUS_IS_OK(status)) {
2250                                 return status;
2251                         }
2252                         SIVAL(nameptr, 0, len);
2253                 }
2254
2255                 p += len;
2256
2257                 len = PTR_DIFF(p, pdata);
2258                 pad = (len + (align-1)) & ~(align-1);
2259                 /*
2260                  * offset to the next entry, the caller
2261                  * will overwrite it for the last entry
2262                  * that's why we always include the padding
2263                  */
2264                 SIVAL(pdata,0,pad);
2265                 /*
2266                  * set padding to zero
2267                  */
2268                 if (do_pad) {
2269                         memset(p, 0, pad - len);
2270                         p = pdata + pad;
2271                 } else {
2272                         p = pdata + len;
2273                 }
2274                 /* End of SMB_QUERY_FILE_UNIX_BASIC */
2275
2276                 break;
2277
2278         default:
2279                 return NT_STATUS_INVALID_LEVEL;
2280         }
2281
2282         if (PTR_DIFF(p,pdata) > space_remaining) {
2283                 DEBUG(9,("smbd_marshall_dir_entry: out of space "
2284                         "(wanted %u, had %d)\n",
2285                         (unsigned int)PTR_DIFF(p,pdata),
2286                         space_remaining ));
2287                 return STATUS_MORE_ENTRIES; /* Not finished - just out of space */
2288         }
2289
2290         /* Setup the last entry pointer, as an offset from base_data */
2291         *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
2292         /* Advance the data pointer to the next slot */
2293         *ppdata = p;
2294
2295         return NT_STATUS_OK;
2296 }
2297
2298 NTSTATUS smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
2299                                connection_struct *conn,
2300                                struct dptr_struct *dirptr,
2301                                uint16_t flags2,
2302                                const char *path_mask,
2303                                uint32_t dirtype,
2304                                int info_level,
2305                                int requires_resume_key,
2306                                bool dont_descend,
2307                                bool ask_sharemode,
2308                                uint8_t align,
2309                                bool do_pad,
2310                                char **ppdata,
2311                                char *base_data,
2312                                char *end_data,
2313                                int space_remaining,
2314                                bool *got_exact_match,
2315                                int *_last_entry_off,
2316                                struct ea_list *name_list)
2317 {
2318         const char *p;
2319         const char *mask = NULL;
2320         long prev_dirpos = 0;
2321         uint32_t mode = 0;
2322         char *fname = NULL;
2323         struct smb_filename *smb_fname = NULL;
2324         struct smbd_dirptr_lanman2_state state;
2325         bool ok;
2326         uint64_t last_entry_off = 0;
2327         NTSTATUS status;
2328
2329         ZERO_STRUCT(state);
2330         state.conn = conn;
2331         state.info_level = info_level;
2332         state.check_mangled_names = lp_mangled_names(conn->params);
2333         state.has_wild = dptr_has_wild(dirptr);
2334         state.got_exact_match = false;
2335
2336         *got_exact_match = false;
2337
2338         p = strrchr_m(path_mask,'/');
2339         if(p != NULL) {
2340                 if(p[1] == '\0') {
2341                         mask = "*.*";
2342                 } else {
2343                         mask = p+1;
2344                 }
2345         } else {
2346                 mask = path_mask;
2347         }
2348
2349         ok = smbd_dirptr_get_entry(ctx,
2350                                    dirptr,
2351                                    mask,
2352                                    dirtype,
2353                                    dont_descend,
2354                                    ask_sharemode,
2355                                    smbd_dirptr_lanman2_match_fn,
2356                                    smbd_dirptr_lanman2_mode_fn,
2357                                    &state,
2358                                    &fname,
2359                                    &smb_fname,
2360                                    &mode,
2361                                    &prev_dirpos);
2362         if (!ok) {
2363                 return NT_STATUS_END_OF_FILE;
2364         }
2365
2366         *got_exact_match = state.got_exact_match;
2367
2368         status = smbd_marshall_dir_entry(ctx,
2369                                      conn,
2370                                      flags2,
2371                                      info_level,
2372                                      name_list,
2373                                      state.check_mangled_names,
2374                                      requires_resume_key,
2375                                      mode,
2376                                      fname,
2377                                      smb_fname,
2378                                      space_remaining,
2379                                      align,
2380                                      do_pad,
2381                                      base_data,
2382                                      ppdata,
2383                                      end_data,
2384                                      &last_entry_off);
2385         if (NT_STATUS_EQUAL(status, NT_STATUS_ILLEGAL_CHARACTER)) {
2386                 DEBUG(1,("Conversion error: illegal character: %s\n",
2387                          smb_fname_str_dbg(smb_fname)));
2388         }
2389         TALLOC_FREE(fname);
2390         TALLOC_FREE(smb_fname);
2391         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2392                 dptr_SeekDir(dirptr, prev_dirpos);
2393                 return status;
2394         }
2395         if (!NT_STATUS_IS_OK(status)) {
2396                 return status;
2397         }
2398
2399         *_last_entry_off = last_entry_off;
2400         return NT_STATUS_OK;
2401 }
2402
2403 static NTSTATUS get_lanman2_dir_entry(TALLOC_CTX *ctx,
2404                                 connection_struct *conn,
2405                                 struct dptr_struct *dirptr,
2406                                 uint16_t flags2,
2407                                 const char *path_mask,
2408                                 uint32_t dirtype,
2409                                 int info_level,
2410                                 bool requires_resume_key,
2411                                 bool dont_descend,
2412                                 bool ask_sharemode,
2413                                 char **ppdata,
2414                                 char *base_data,
2415                                 char *end_data,
2416                                 int space_remaining,
2417                                 bool *got_exact_match,
2418                                 int *last_entry_off,
2419                                 struct ea_list *name_list)
2420 {
2421         uint8_t align = 4;
2422         const bool do_pad = true;
2423
2424         if (info_level >= 1 && info_level <= 3) {
2425                 /* No alignment on earlier info levels. */
2426                 align = 1;
2427         }
2428
2429         return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
2430                                          path_mask, dirtype, info_level,
2431                                          requires_resume_key, dont_descend, ask_sharemode,
2432                                          align, do_pad,
2433                                          ppdata, base_data, end_data,
2434                                          space_remaining,
2435                                          got_exact_match,
2436                                          last_entry_off, name_list);
2437 }
2438
2439 /****************************************************************************
2440  Reply to a TRANS2_FINDFIRST.
2441 ****************************************************************************/
2442
2443 static void call_trans2findfirst(connection_struct *conn,
2444                                  struct smb_request *req,
2445                                  char **pparams, int total_params,
2446                                  char **ppdata, int total_data,
2447                                  unsigned int max_data_bytes)
2448 {
2449         /* We must be careful here that we don't return more than the
2450                 allowed number of data bytes. If this means returning fewer than
2451                 maxentries then so be it. We assume that the redirector has
2452                 enough room for the fixed number of parameter bytes it has
2453                 requested. */
2454         struct smb_filename *smb_dname = NULL;
2455         char *params = *pparams;
2456         char *pdata = *ppdata;
2457         char *data_end;
2458         uint32_t dirtype;
2459         int maxentries;
2460         uint16_t findfirst_flags;
2461         bool close_after_first;
2462         bool close_if_end;
2463         bool requires_resume_key;
2464         int info_level;
2465         char *directory = NULL;
2466         char *mask = NULL;
2467         char *p;
2468         int last_entry_off=0;
2469         int dptr_num = -1;
2470         int numentries = 0;
2471         int i;
2472         bool finished = False;
2473         bool dont_descend = False;
2474         bool out_of_space = False;
2475         int space_remaining;
2476         bool mask_contains_wcard = False;
2477         struct ea_list *ea_list = NULL;
2478         NTSTATUS ntstatus = NT_STATUS_OK;
2479         bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2480         TALLOC_CTX *ctx = talloc_tos();
2481         struct dptr_struct *dirptr = NULL;
2482         struct smbd_server_connection *sconn = req->sconn;
2483         uint32_t ucf_flags = (UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP);
2484         bool backup_priv = false;
2485         bool as_root = false;
2486
2487         if (total_params < 13) {
2488                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2489                 goto out;
2490         }
2491
2492         dirtype = SVAL(params,0);
2493         maxentries = SVAL(params,2);
2494         findfirst_flags = SVAL(params,4);
2495         close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
2496         close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2497         requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2498         backup_priv = ((findfirst_flags & FLAG_TRANS2_FIND_BACKUP_INTENT) &&
2499                                 security_token_has_privilege(get_current_nttok(conn),
2500                                                 SEC_PRIV_BACKUP));
2501
2502         info_level = SVAL(params,6);
2503
2504         DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2505 close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_data_bytes = %d\n",
2506                 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
2507                 (int)backup_priv,
2508                 info_level, max_data_bytes));
2509
2510         if (!maxentries) {
2511                 /* W2K3 seems to treat zero as 1. */
2512                 maxentries = 1;
2513         }
2514
2515         switch (info_level) {
2516                 case SMB_FIND_INFO_STANDARD:
2517                 case SMB_FIND_EA_SIZE:
2518                 case SMB_FIND_EA_LIST:
2519                 case SMB_FIND_FILE_DIRECTORY_INFO:
2520                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2521                 case SMB_FIND_FILE_NAMES_INFO:
2522                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2523                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2524                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2525                         break;
2526                 case SMB_FIND_FILE_UNIX:
2527                 case SMB_FIND_FILE_UNIX_INFO2:
2528                         /* Always use filesystem for UNIX mtime query. */
2529                         ask_sharemode = false;
2530                         if (!lp_unix_extensions()) {
2531                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2532                                 goto out;
2533                         }
2534                         ucf_flags |= UCF_UNIX_NAME_LOOKUP;
2535                         break;
2536                 default:
2537                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2538                         goto out;
2539         }
2540
2541         srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
2542                               params+12, total_params - 12,
2543                               STR_TERMINATE, &ntstatus, &mask_contains_wcard);
2544         if (!NT_STATUS_IS_OK(ntstatus)) {
2545                 reply_nterror(req, ntstatus);
2546                 goto out;
2547         }
2548
2549         if (backup_priv) {
2550                 become_root();
2551                 as_root = true;
2552                 ntstatus = filename_convert_with_privilege(ctx,
2553                                 conn,
2554                                 req,
2555                                 directory,
2556                                 ucf_flags,
2557                                 &mask_contains_wcard,
2558                                 &smb_dname);
2559         } else {
2560                 ntstatus = filename_convert(ctx, conn,
2561                                     req->flags2 & FLAGS2_DFS_PATHNAMES,
2562                                     directory,
2563                                     ucf_flags,
2564                                     &mask_contains_wcard,
2565                                     &smb_dname);
2566         }
2567
2568         if (!NT_STATUS_IS_OK(ntstatus)) {
2569                 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
2570                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2571                                         ERRSRV, ERRbadpath);
2572                         goto out;
2573                 }
2574                 reply_nterror(req, ntstatus);
2575                 goto out;
2576         }
2577
2578         mask = smb_dname->original_lcomp;
2579
2580         directory = smb_dname->base_name;
2581
2582         p = strrchr_m(directory,'/');
2583         if(p == NULL) {
2584                 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2585                 if((directory[0] == '.') && (directory[1] == '\0')) {
2586                         mask = talloc_strdup(ctx,"*");
2587                         if (!mask) {
2588                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2589                                 goto out;
2590                         }
2591                         mask_contains_wcard = True;
2592                 }
2593         } else {
2594                 *p = 0;
2595         }
2596
2597         if (p == NULL || p == directory) {
2598                 /* Ensure we don't have a directory name of "". */
2599                 directory = talloc_strdup(talloc_tos(), ".");
2600                 if (!directory) {
2601                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2602                         goto out;
2603                 }
2604         }
2605
2606         DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
2607
2608         if (info_level == SMB_FIND_EA_LIST) {
2609                 uint32_t ea_size;
2610
2611                 if (total_data < 4) {
2612                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2613                         goto out;
2614                 }
2615
2616                 ea_size = IVAL(pdata,0);
2617                 if (ea_size != total_data) {
2618                         DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2619 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2620                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2621                         goto out;
2622                 }
2623
2624                 if (!lp_ea_support(SNUM(conn))) {
2625                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
2626                         goto out;
2627                 }
2628
2629                 /* Pull out the list of names. */
2630                 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2631                 if (!ea_list) {
2632                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2633                         goto out;
2634                 }
2635         }
2636
2637         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
2638                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2639                 goto out;
2640         }
2641
2642         *ppdata = (char *)SMB_REALLOC(
2643                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2644         if(*ppdata == NULL ) {
2645                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2646                 goto out;
2647         }
2648         pdata = *ppdata;
2649         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2650         /*
2651          * squash valgrind "writev(vector[...]) points to uninitialised byte(s)"
2652          * error.
2653          */
2654         memset(pdata + total_data, 0, ((max_data_bytes + DIR_ENTRY_SAFETY_MARGIN) - total_data));
2655         /* Realloc the params space */
2656         *pparams = (char *)SMB_REALLOC(*pparams, 10);
2657         if (*pparams == NULL) {
2658                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2659                 goto out;
2660         }
2661         params = *pparams;
2662
2663         /* Save the wildcard match and attribs we are using on this directory -
2664                 needed as lanman2 assumes these are being saved between calls */
2665
2666         ntstatus = dptr_create(conn,
2667                                 req,
2668                                 NULL, /* fsp */
2669                                 directory,
2670                                 False,
2671                                 True,
2672                                 req->smbpid,
2673                                 mask,
2674                                 mask_contains_wcard,
2675                                 dirtype,
2676                                 &dirptr);
2677
2678         if (!NT_STATUS_IS_OK(ntstatus)) {
2679                 reply_nterror(req, ntstatus);
2680                 goto out;
2681         }
2682
2683         if (backup_priv) {
2684                 /* Remember this in case we have
2685                    to do a findnext. */
2686                 dptr_set_priv(dirptr);
2687         }
2688
2689         dptr_num = dptr_dnum(dirptr);
2690         DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
2691
2692         /* Initialize per TRANS2_FIND_FIRST operation data */
2693         dptr_init_search_op(dirptr);
2694
2695         /* We don't need to check for VOL here as this is returned by
2696                 a different TRANS2 call. */
2697
2698         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2699                  directory,lp_dont_descend(ctx, SNUM(conn))));
2700         if (in_list(directory,lp_dont_descend(ctx, SNUM(conn)),conn->case_sensitive))
2701                 dont_descend = True;
2702
2703         p = pdata;
2704         space_remaining = max_data_bytes;
2705         out_of_space = False;
2706
2707         for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
2708                 bool got_exact_match = False;
2709
2710                 /* this is a heuristic to avoid seeking the dirptr except when
2711                         absolutely necessary. It allows for a filename of about 40 chars */
2712                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2713                         out_of_space = True;
2714                         finished = False;
2715                 } else {
2716                         ntstatus = get_lanman2_dir_entry(ctx,
2717                                         conn,
2718                                         dirptr,
2719                                         req->flags2,
2720                                         mask,dirtype,info_level,
2721                                         requires_resume_key,dont_descend,
2722                                         ask_sharemode,
2723                                         &p,pdata,data_end,
2724                                         space_remaining,
2725                                         &got_exact_match,
2726                                         &last_entry_off, ea_list);
2727                         if (NT_STATUS_EQUAL(ntstatus,
2728                                         NT_STATUS_ILLEGAL_CHARACTER)) {
2729                                 /*
2730                                  * Bad character conversion on name. Ignore this
2731                                  * entry.
2732                                  */
2733                                 continue;
2734                         }
2735                         if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
2736                                 out_of_space = true;
2737                         } else {
2738                                 finished = !NT_STATUS_IS_OK(ntstatus);
2739                         }
2740                 }
2741
2742                 if (!finished && !out_of_space)
2743                         numentries++;
2744
2745                 /*
2746                  * As an optimisation if we know we aren't looking
2747                  * for a wildcard name (ie. the name matches the wildcard exactly)
2748                  * then we can finish on any (first) match.
2749                  * This speeds up large directory searches. JRA.
2750                  */
2751
2752                 if(got_exact_match)
2753                         finished = True;
2754
2755                 /* Ensure space_remaining never goes -ve. */
2756                 if (PTR_DIFF(p,pdata) > max_data_bytes) {
2757                         space_remaining = 0;
2758                         out_of_space = true;
2759                 } else {
2760                         space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2761                 }
2762         }
2763
2764         /* Check if we can close the dirptr */
2765         if(close_after_first || (finished && close_if_end)) {
2766                 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
2767                 dptr_close(sconn, &dptr_num);
2768         }
2769
2770         /*
2771          * If there are no matching entries we must return ERRDOS/ERRbadfile -
2772          * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2773          * the protocol level is less than NT1. Tested with smbclient. JRA.
2774          * This should fix the OS/2 client bug #2335.
2775          */
2776
2777         if(numentries == 0) {
2778                 dptr_close(sconn, &dptr_num);
2779                 if (get_Protocol() < PROTOCOL_NT1) {
2780                         reply_force_doserror(req, ERRDOS, ERRnofiles);
2781                         goto out;
2782                 } else {
2783                         reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
2784                                         ERRDOS, ERRbadfile);
2785                         goto out;
2786                 }
2787         }
2788
2789         /* At this point pdata points to numentries directory entries. */
2790
2791         /* Set up the return parameter block */
2792         SSVAL(params,0,dptr_num);
2793         SSVAL(params,2,numentries);
2794         SSVAL(params,4,finished);
2795         SSVAL(params,6,0); /* Never an EA error */
2796         SSVAL(params,8,last_entry_off);
2797
2798         send_trans2_replies(conn, req, NT_STATUS_OK, params, 10, pdata, PTR_DIFF(p,pdata),
2799                             max_data_bytes);
2800
2801         if ((! *directory) && dptr_path(sconn, dptr_num)) {
2802                 directory = talloc_strdup(talloc_tos(),dptr_path(sconn, dptr_num));
2803                 if (!directory) {
2804                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2805                 }
2806         }
2807
2808         DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2809                 smb_fn_name(req->cmd),
2810                 mask, directory, dirtype, numentries ) );
2811
2812         /*
2813          * Force a name mangle here to ensure that the
2814          * mask as an 8.3 name is top of the mangled cache.
2815          * The reasons for this are subtle. Don't remove
2816          * this code unless you know what you are doing
2817          * (see PR#13758). JRA.
2818          */
2819
2820         if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
2821                 char mangled_name[13];
2822                 name_to_8_3(mask, mangled_name, True, conn->params);
2823         }
2824  out:
2825
2826         if (as_root) {
2827                 unbecome_root();
2828         }
2829
2830         TALLOC_FREE(smb_dname);
2831         return;
2832 }
2833
2834 /****************************************************************************
2835  Reply to a TRANS2_FINDNEXT.
2836 ****************************************************************************/
2837
2838 static void call_trans2findnext(connection_struct *conn,
2839                                 struct smb_request *req,
2840                                 char **pparams, int total_params,
2841                                 char **ppdata, int total_data,
2842                                 unsigned int max_data_bytes)
2843 {
2844         /* We must be careful here that we don't return more than the
2845                 allowed number of data bytes. If this means returning fewer than
2846                 maxentries then so be it. We assume that the redirector has
2847                 enough room for the fixed number of parameter bytes it has
2848                 requested. */
2849         char *params = *pparams;
2850         char *pdata = *ppdata;
2851         char *data_end;
2852         int dptr_num;
2853         int maxentries;
2854         uint16_t info_level;
2855         uint32_t resume_key;
2856         uint16_t findnext_flags;
2857         bool close_after_request;
2858         bool close_if_end;
2859         bool requires_resume_key;
2860         bool continue_bit;
2861         bool mask_contains_wcard = False;
2862         char *resume_name = NULL;
2863         const char *mask = NULL;
2864         const char *directory = NULL;
2865         char *p = NULL;
2866         uint16_t dirtype;
2867         int numentries = 0;
2868         int i, last_entry_off=0;
2869         bool finished = False;
2870         bool dont_descend = False;
2871         bool out_of_space = False;
2872         int space_remaining;
2873         struct ea_list *ea_list = NULL;
2874         NTSTATUS ntstatus = NT_STATUS_OK;
2875         bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2876         TALLOC_CTX *ctx = talloc_tos();
2877         struct dptr_struct *dirptr;
2878         struct smbd_server_connection *sconn = req->sconn;
2879         bool backup_priv = false; 
2880         bool as_root = false;
2881
2882         if (total_params < 13) {
2883                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2884                 return;
2885         }
2886
2887         dptr_num = SVAL(params,0);
2888         maxentries = SVAL(params,2);
2889         info_level = SVAL(params,4);
2890         resume_key = IVAL(params,6);
2891         findnext_flags = SVAL(params,10);
2892         close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
2893         close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2894         requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2895         continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
2896
2897         if (!continue_bit) {
2898                 /* We only need resume_name if continue_bit is zero. */
2899                 srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
2900                               params+12,
2901                               total_params - 12, STR_TERMINATE, &ntstatus,
2902                               &mask_contains_wcard);
2903                 if (!NT_STATUS_IS_OK(ntstatus)) {
2904                         /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2905                            complain (it thinks we're asking for the directory above the shared
2906                            path or an invalid name). Catch this as the resume name is only compared, never used in
2907                            a file access. JRA. */
2908                         srvstr_pull_talloc(ctx, params, req->flags2,
2909                                 &resume_name, params+12,
2910                                 total_params - 12,
2911                                 STR_TERMINATE);
2912
2913                         if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
2914                                 reply_nterror(req, ntstatus);
2915                                 return;
2916                         }
2917                 }
2918         }
2919
2920         DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2921 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2922 resume_key = %d resume name = %s continue=%d level = %d\n",
2923                 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end, 
2924                 requires_resume_key, resume_key,
2925                 resume_name ? resume_name : "(NULL)", continue_bit, info_level));
2926
2927         if (!maxentries) {
2928                 /* W2K3 seems to treat zero as 1. */
2929                 maxentries = 1;
2930         }
2931
2932         switch (info_level) {
2933                 case SMB_FIND_INFO_STANDARD:
2934                 case SMB_FIND_EA_SIZE:
2935                 case SMB_FIND_EA_LIST:
2936                 case SMB_FIND_FILE_DIRECTORY_INFO:
2937                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2938                 case SMB_FIND_FILE_NAMES_INFO:
2939                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2940                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2941                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2942                         break;
2943                 case SMB_FIND_FILE_UNIX:
2944                 case SMB_FIND_FILE_UNIX_INFO2:
2945                         /* Always use filesystem for UNIX mtime query. */
2946                         ask_sharemode = false;
2947                         if (!lp_unix_extensions()) {
2948                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2949                                 return;
2950                         }
2951                         break;
2952                 default:
2953                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2954                         return;
2955         }
2956
2957         if (info_level == SMB_FIND_EA_LIST) {
2958                 uint32_t ea_size;
2959
2960                 if (total_data < 4) {
2961                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2962                         return;
2963                 }
2964
2965                 ea_size = IVAL(pdata,0);
2966                 if (ea_size != total_data) {
2967                         DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2968 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2969                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2970                         return;
2971                 }
2972
2973                 if (!lp_ea_support(SNUM(conn))) {
2974                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
2975                         return;
2976                 }
2977
2978                 /* Pull out the list of names. */
2979                 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2980                 if (!ea_list) {
2981                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2982                         return;
2983                 }
2984         }
2985
2986         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
2987                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2988                 return;
2989         }
2990
2991         *ppdata = (char *)SMB_REALLOC(
2992                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2993         if(*ppdata == NULL) {
2994                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2995                 return;
2996         }
2997
2998         pdata = *ppdata;
2999         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
3000
3001         /*
3002          * squash valgrind "writev(vector[...]) points to uninitialised byte(s)"
3003          * error.
3004          */
3005         memset(pdata + total_data, 0, (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN) - total_data);
3006         /* Realloc the params space */
3007         *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
3008         if(*pparams == NULL ) {
3009                 reply_nterror(req, NT_STATUS_NO_MEMORY);
3010                 return;
3011         }
3012
3013         params = *pparams;
3014
3015         /* Check that the dptr is valid */
3016         if(!(dirptr = dptr_fetch_lanman2(sconn, dptr_num))) {
3017                 reply_nterror(req, STATUS_NO_MORE_FILES);
3018                 return;
3019         }
3020
3021         directory = dptr_path(sconn, dptr_num);
3022
3023         /* Get the wildcard mask from the dptr */
3024         if((mask = dptr_wcard(sconn, dptr_num))== NULL) {
3025                 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
3026                 reply_nterror(req, STATUS_NO_MORE_FILES);
3027                 return;
3028         }
3029
3030         /* Get the attr mask from the dptr */
3031         dirtype = dptr_attr(sconn, dptr_num);
3032
3033         backup_priv = dptr_get_priv(dirptr);
3034
3035         DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld) "
3036                 "backup_priv = %d\n",
3037                 dptr_num, mask, dirtype,
3038                 (long)dirptr,
3039                 dptr_TellDir(dirptr),
3040                 (int)backup_priv));
3041
3042         /* Initialize per TRANS2_FIND_NEXT operation data */
3043         dptr_init_search_op(dirptr);
3044
3045         /* We don't need to check for VOL here as this is returned by
3046                 a different TRANS2 call. */
3047
3048         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
3049                  directory,lp_dont_descend(ctx, SNUM(conn))));
3050         if (in_list(directory,lp_dont_descend(ctx, SNUM(conn)),conn->case_sensitive))
3051                 dont_descend = True;
3052
3053         p = pdata;
3054         space_remaining = max_data_bytes;
3055         out_of_space = False;
3056
3057         if (backup_priv) {
3058                 become_root();
3059                 as_root = true;
3060         }
3061
3062         /*
3063          * Seek to the correct position. We no longer use the resume key but
3064          * depend on the last file name instead.
3065          */
3066
3067         if(!continue_bit && resume_name && *resume_name) {
3068                 SMB_STRUCT_STAT st;
3069
3070                 long current_pos = 0;
3071                 /*
3072                  * Remember, name_to_8_3 is called by
3073                  * get_lanman2_dir_entry(), so the resume name
3074                  * could be mangled. Ensure we check the unmangled name.
3075                  */
3076
3077                 if (mangle_is_mangled(resume_name, conn->params)) {
3078                         char *new_resume_name = NULL;
3079                         mangle_lookup_name_from_8_3(ctx,
3080                                                 resume_name,
3081                                                 &new_resume_name,
3082                                                 conn->params);
3083                         if (new_resume_name) {
3084                                 resume_name = new_resume_name;
3085                         }
3086                 }
3087
3088                 /*
3089                  * Fix for NT redirector problem triggered by resume key indexes
3090                  * changing between directory scans. We now return a resume key of 0
3091                  * and instead look for the filename to continue from (also given
3092                  * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
3093                  * findfirst/findnext (as is usual) then the directory pointer
3094                  * should already be at the correct place.
3095                  */
3096
3097                 finished = !dptr_SearchDir(dirptr, resume_name, &current_pos, &st);
3098         } /* end if resume_name && !continue_bit */
3099
3100         for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
3101                 bool got_exact_match = False;
3102
3103                 /* this is a heuristic to avoid seeking the dirptr except when 
3104                         absolutely necessary. It allows for a filename of about 40 chars */
3105                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
3106                         out_of_space = True;
3107                         finished = False;
3108                 } else {
3109                         ntstatus = get_lanman2_dir_entry(ctx,
3110                                                 conn,
3111                                                 dirptr,
3112                                                 req->flags2,
3113                                                 mask,dirtype,info_level,
3114                                                 requires_resume_key,dont_descend,
3115                                                 ask_sharemode,
3116                                                 &p,pdata,data_end,
3117                                                 space_remaining,
3118                                                 &got_exact_match,
3119                                                 &last_entry_off, ea_list);
3120                         if (NT_STATUS_EQUAL(ntstatus,
3121                                         NT_STATUS_ILLEGAL_CHARACTER)) {
3122                                 /*
3123                                  * Bad character conversion on name. Ignore this
3124                                  * entry.
3125                                  */
3126                                 continue;
3127                         }
3128                         if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
3129                                 out_of_space = true;
3130                         } else {
3131                                 finished = !NT_STATUS_IS_OK(ntstatus);
3132                         }
3133                 }
3134
3135                 if (!finished && !out_of_space)
3136                         numentries++;
3137
3138                 /*
3139                  * As an optimisation if we know we aren't looking
3140                  * for a wildcard name (ie. the name matches the wildcard exactly)
3141                  * then we can finish on any (first) match.
3142                  * This speeds up large directory searches. JRA.
3143                  */
3144
3145                 if(got_exact_match)
3146                         finished = True;
3147
3148                 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
3149         }
3150
3151         DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
3152                 smb_fn_name(req->cmd),
3153                 mask, directory, dirtype, numentries ) );
3154
3155         /* Check if we can close the dirptr */
3156         if(close_after_request || (finished && close_if_end)) {
3157                 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
3158                 dptr_close(sconn, &dptr_num); /* This frees up the saved mask */
3159         }
3160
3161         if (as_root) {
3162                 unbecome_root();
3163         }
3164
3165         /* Set up the return parameter block */
3166         SSVAL(params,0,numentries);
3167         SSVAL(params,2,finished);
3168         SSVAL(params,4,0); /* Never an EA error */
3169         SSVAL(params,6,last_entry_off);
3170
3171         send_trans2_replies(conn, req, NT_STATUS_OK, params, 8, pdata, PTR_DIFF(p,pdata),
3172                             max_data_bytes);
3173
3174         return;
3175 }
3176
3177 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
3178 {
3179         E_md4hash(lp_servicename(talloc_tos(), SNUM(conn)),objid);
3180         return objid;
3181 }
3182
3183 static void samba_extended_info_version(struct smb_extended_info *extended_info)
3184 {
3185         SMB_ASSERT(extended_info != NULL);
3186
3187         extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
3188         extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
3189                                        | ((SAMBA_VERSION_MINOR & 0xff) << 16)
3190                                        | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
3191 #ifdef SAMBA_VERSION_REVISION
3192         extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
3193 #endif
3194         extended_info->samba_subversion = 0;
3195 #ifdef SAMBA_VERSION_RC_RELEASE
3196         extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
3197 #else
3198 #ifdef SAMBA_VERSION_PRE_RELEASE
3199         extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
3200 #endif
3201 #endif
3202 #ifdef SAMBA_VERSION_VENDOR_PATCH
3203         extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
3204 #endif
3205         extended_info->samba_gitcommitdate = 0;
3206 #ifdef SAMBA_VERSION_COMMIT_TIME
3207         unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_COMMIT_TIME);
3208 #endif
3209
3210         memset(extended_info->samba_version_string, 0,
3211                sizeof(extended_info->samba_version_string));
3212
3213         snprintf (extended_info->samba_version_string,
3214                   sizeof(extended_info->samba_version_string),
3215                   "%s", samba_version_string());
3216 }
3217
3218 NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
3219                          connection_struct *conn,
3220                          TALLOC_CTX *mem_ctx,
3221                          uint16_t info_level,
3222                          uint16_t flags2,
3223                          unsigned int max_data_bytes,
3224                          size_t *fixed_portion,
3225                          struct smb_filename *fname,
3226                          char **ppdata,
3227                          int *ret_data_len)
3228 {
3229         char *pdata, *end_data;
3230         int data_len = 0;
3231         size_t len = 0;
3232         const char *vname = volume_label(talloc_tos(), SNUM(conn));
3233         int snum = SNUM(conn);
3234         const char *fstype = lp_fstype(SNUM(conn));
3235         const char *filename = NULL;
3236         const uint64_t bytes_per_sector = 512;
3237         uint32_t additional_flags = 0;
3238         struct smb_filename smb_fname;
3239         SMB_STRUCT_STAT st;
3240         NTSTATUS status = NT_STATUS_OK;
3241         uint64_t df_ret;
3242
3243         if (fname == NULL || fname->base_name == NULL) {
3244                 filename = ".";
3245         } else {
3246                 filename = fname->base_name;
3247         }
3248
3249         if (IS_IPC(conn)) {
3250                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
3251                         DEBUG(0,("smbd_do_qfsinfo: not an allowed "
3252                                 "info level (0x%x) on IPC$.\n",
3253                                 (unsigned int)info_level));
3254                         return NT_STATUS_ACCESS_DENIED;
3255                 }
3256         }
3257
3258         DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
3259
3260         ZERO_STRUCT(smb_fname);
3261         smb_fname.base_name = discard_const_p(char, filename);
3262
3263         if(SMB_VFS_STAT(conn, &smb_fname) != 0) {
3264                 DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
3265                 return map_nt_error_from_unix(errno);
3266         }
3267
3268         st = smb_fname.st;
3269
3270         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
3271                 return NT_STATUS_INVALID_PARAMETER;
3272         }
3273
3274         *ppdata = (char *)SMB_REALLOC(
3275                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
3276         if (*ppdata == NULL) {
3277                 return NT_STATUS_NO_MEMORY;
3278         }
3279
3280         pdata = *ppdata;
3281         memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
3282         end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
3283
3284         *fixed_portion = 0;
3285
3286         switch (info_level) {
3287                 case SMB_INFO_ALLOCATION:
3288                 {
3289                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
3290                         data_len = 18;
3291                         df_ret = get_dfree_info(conn, filename, &bsize, &dfree,
3292                                                 &dsize);
3293                         if (df_ret == (uint64_t)-1) {
3294                                 return map_nt_error_from_unix(errno);
3295                         }
3296
3297                         block_size = lp_block_size(snum);
3298                         if (bsize < block_size) {
3299                                 uint64_t factor = block_size/bsize;
3300                                 bsize = block_size;
3301                                 dsize /= factor;
3302                                 dfree /= factor;
3303                         }
3304                         if (bsize > block_size) {
3305                                 uint64_t factor = bsize/block_size;
3306                                 bsize = block_size;
3307                                 dsize *= factor;
3308                                 dfree *= factor;
3309                         }
3310                         sectors_per_unit = bsize/bytes_per_sector;
3311
3312                         DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
3313 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
3314                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
3315
3316                        &nbs