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