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