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