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