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