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