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