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