smbd: ZERO_STRUCT -> struct init
[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 *)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 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 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 flags = 0;
1089         NTSTATUS status;
1090         uint32 access_mask;
1091         uint32 share_mode;
1092         uint32 create_disposition;
1093         uint32 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)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 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 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 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,
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)file_size);
1709                 SIVAL(p,16,(uint32)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)file_size);
1748                 SIVAL(p,16,(uint32)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)file_size);
1798                 SIVAL(p,16,(uint32)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 flags2,
2294                                const char *path_mask,
2295                                uint32 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         TALLOC_FREE(fname);
2378         TALLOC_FREE(smb_fname);
2379         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2380                 dptr_SeekDir(dirptr, prev_dirpos);
2381                 return status;
2382         }
2383         if (!NT_STATUS_IS_OK(status)) {
2384                 return status;
2385         }
2386
2387         *_last_entry_off = last_entry_off;
2388         return NT_STATUS_OK;
2389 }
2390
2391 static NTSTATUS get_lanman2_dir_entry(TALLOC_CTX *ctx,
2392                                 connection_struct *conn,
2393                                 struct dptr_struct *dirptr,
2394                                 uint16 flags2,
2395                                 const char *path_mask,
2396                                 uint32 dirtype,
2397                                 int info_level,
2398                                 bool requires_resume_key,
2399                                 bool dont_descend,
2400                                 bool ask_sharemode,
2401                                 char **ppdata,
2402                                 char *base_data,
2403                                 char *end_data,
2404                                 int space_remaining,
2405                                 bool *got_exact_match,
2406                                 int *last_entry_off,
2407                                 struct ea_list *name_list)
2408 {
2409         uint8_t align = 4;
2410         const bool do_pad = true;
2411
2412         if (info_level >= 1 && info_level <= 3) {
2413                 /* No alignment on earlier info levels. */
2414                 align = 1;
2415         }
2416
2417         return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
2418                                          path_mask, dirtype, info_level,
2419                                          requires_resume_key, dont_descend, ask_sharemode,
2420                                          align, do_pad,
2421                                          ppdata, base_data, end_data,
2422                                          space_remaining,
2423                                          got_exact_match,
2424                                          last_entry_off, name_list);
2425 }
2426
2427 /****************************************************************************
2428  Reply to a TRANS2_FINDFIRST.
2429 ****************************************************************************/
2430
2431 static void call_trans2findfirst(connection_struct *conn,
2432                                  struct smb_request *req,
2433                                  char **pparams, int total_params,
2434                                  char **ppdata, int total_data,
2435                                  unsigned int max_data_bytes)
2436 {
2437         /* We must be careful here that we don't return more than the
2438                 allowed number of data bytes. If this means returning fewer than
2439                 maxentries then so be it. We assume that the redirector has
2440                 enough room for the fixed number of parameter bytes it has
2441                 requested. */
2442         struct smb_filename *smb_dname = NULL;
2443         char *params = *pparams;
2444         char *pdata = *ppdata;
2445         char *data_end;
2446         uint32 dirtype;
2447         int maxentries;
2448         uint16 findfirst_flags;
2449         bool close_after_first;
2450         bool close_if_end;
2451         bool requires_resume_key;
2452         int info_level;
2453         char *directory = NULL;
2454         char *mask = NULL;
2455         char *p;
2456         int last_entry_off=0;
2457         int dptr_num = -1;
2458         int numentries = 0;
2459         int i;
2460         bool finished = False;
2461         bool dont_descend = False;
2462         bool out_of_space = False;
2463         int space_remaining;
2464         bool mask_contains_wcard = False;
2465         struct ea_list *ea_list = NULL;
2466         NTSTATUS ntstatus = NT_STATUS_OK;
2467         bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2468         TALLOC_CTX *ctx = talloc_tos();
2469         struct dptr_struct *dirptr = NULL;
2470         struct smbd_server_connection *sconn = req->sconn;
2471         uint32_t ucf_flags = (UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP);
2472         bool backup_priv = false;
2473
2474         if (total_params < 13) {
2475                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2476                 goto out;
2477         }
2478
2479         dirtype = SVAL(params,0);
2480         maxentries = SVAL(params,2);
2481         findfirst_flags = SVAL(params,4);
2482         close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
2483         close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2484         requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2485         backup_priv = ((findfirst_flags & FLAG_TRANS2_FIND_BACKUP_INTENT) &&
2486                                 security_token_has_privilege(get_current_nttok(conn),
2487                                                 SEC_PRIV_BACKUP));
2488
2489         info_level = SVAL(params,6);
2490
2491         DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2492 close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_data_bytes = %d\n",
2493                 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
2494                 (int)backup_priv,
2495                 info_level, max_data_bytes));
2496
2497         if (!maxentries) {
2498                 /* W2K3 seems to treat zero as 1. */
2499                 maxentries = 1;
2500         }
2501
2502         switch (info_level) {
2503                 case SMB_FIND_INFO_STANDARD:
2504                 case SMB_FIND_EA_SIZE:
2505                 case SMB_FIND_EA_LIST:
2506                 case SMB_FIND_FILE_DIRECTORY_INFO:
2507                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2508                 case SMB_FIND_FILE_NAMES_INFO:
2509                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2510                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2511                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2512                         break;
2513                 case SMB_FIND_FILE_UNIX:
2514                 case SMB_FIND_FILE_UNIX_INFO2:
2515                         /* Always use filesystem for UNIX mtime query. */
2516                         ask_sharemode = false;
2517                         if (!lp_unix_extensions()) {
2518                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2519                                 goto out;
2520                         }
2521                         ucf_flags |= UCF_UNIX_NAME_LOOKUP;
2522                         break;
2523                 default:
2524                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2525                         goto out;
2526         }
2527
2528         srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
2529                               params+12, total_params - 12,
2530                               STR_TERMINATE, &ntstatus, &mask_contains_wcard);
2531         if (!NT_STATUS_IS_OK(ntstatus)) {
2532                 reply_nterror(req, ntstatus);
2533                 goto out;
2534         }
2535
2536         if (backup_priv) {
2537                 become_root();
2538                 ntstatus = filename_convert_with_privilege(ctx,
2539                                 conn,
2540                                 req,
2541                                 directory,
2542                                 ucf_flags,
2543                                 &mask_contains_wcard,
2544                                 &smb_dname);
2545         } else {
2546                 ntstatus = filename_convert(ctx, conn,
2547                                     req->flags2 & FLAGS2_DFS_PATHNAMES,
2548                                     directory,
2549                                     ucf_flags,
2550                                     &mask_contains_wcard,
2551                                     &smb_dname);
2552         }
2553
2554         if (!NT_STATUS_IS_OK(ntstatus)) {
2555                 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
2556                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2557                                         ERRSRV, ERRbadpath);
2558                         goto out;
2559                 }
2560                 reply_nterror(req, ntstatus);
2561                 goto out;
2562         }
2563
2564         mask = smb_dname->original_lcomp;
2565
2566         directory = smb_dname->base_name;
2567
2568         p = strrchr_m(directory,'/');
2569         if(p == NULL) {
2570                 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2571                 if((directory[0] == '.') && (directory[1] == '\0')) {
2572                         mask = talloc_strdup(ctx,"*");
2573                         if (!mask) {
2574                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2575                                 goto out;
2576                         }
2577                         mask_contains_wcard = True;
2578                 }
2579         } else {
2580                 *p = 0;
2581         }
2582
2583         if (p == NULL || p == directory) {
2584                 /* Ensure we don't have a directory name of "". */
2585                 directory = talloc_strdup(talloc_tos(), ".");
2586                 if (!directory) {
2587                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2588                         goto out;
2589                 }
2590         }
2591
2592         DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
2593
2594         if (info_level == SMB_FIND_EA_LIST) {
2595                 uint32 ea_size;
2596
2597                 if (total_data < 4) {
2598                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2599                         goto out;
2600                 }
2601
2602                 ea_size = IVAL(pdata,0);
2603                 if (ea_size != total_data) {
2604                         DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2605 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2606                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2607                         goto out;
2608                 }
2609
2610                 if (!lp_ea_support(SNUM(conn))) {
2611                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
2612                         goto out;
2613                 }
2614
2615                 /* Pull out the list of names. */
2616                 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2617                 if (!ea_list) {
2618                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2619                         goto out;
2620                 }
2621         }
2622
2623         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
2624                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2625                 goto out;
2626         }
2627
2628         *ppdata = (char *)SMB_REALLOC(
2629                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2630         if(*ppdata == NULL ) {
2631                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2632                 goto out;
2633         }
2634         pdata = *ppdata;
2635         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2636
2637         /* Realloc the params space */
2638         *pparams = (char *)SMB_REALLOC(*pparams, 10);
2639         if (*pparams == NULL) {
2640                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2641                 goto out;
2642         }
2643         params = *pparams;
2644
2645         /* Save the wildcard match and attribs we are using on this directory -
2646                 needed as lanman2 assumes these are being saved between calls */
2647
2648         ntstatus = dptr_create(conn,
2649                                 req,
2650                                 NULL, /* fsp */
2651                                 directory,
2652                                 False,
2653                                 True,
2654                                 req->smbpid,
2655                                 mask,
2656                                 mask_contains_wcard,
2657                                 dirtype,
2658                                 &dirptr);
2659
2660         if (!NT_STATUS_IS_OK(ntstatus)) {
2661                 reply_nterror(req, ntstatus);
2662                 goto out;
2663         }
2664
2665         if (backup_priv) {
2666                 /* Remember this in case we have
2667                    to do a findnext. */
2668                 dptr_set_priv(dirptr);
2669         }
2670
2671         dptr_num = dptr_dnum(dirptr);
2672         DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
2673
2674         /* Initialize per TRANS2_FIND_FIRST operation data */
2675         dptr_init_search_op(dirptr);
2676
2677         /* We don't need to check for VOL here as this is returned by
2678                 a different TRANS2 call. */
2679
2680         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
2681                  directory,lp_dont_descend(ctx, SNUM(conn))));
2682         if (in_list(directory,lp_dont_descend(ctx, SNUM(conn)),conn->case_sensitive))
2683                 dont_descend = True;
2684
2685         p = pdata;
2686         space_remaining = max_data_bytes;
2687         out_of_space = False;
2688
2689         for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
2690                 bool got_exact_match = False;
2691
2692                 /* this is a heuristic to avoid seeking the dirptr except when
2693                         absolutely necessary. It allows for a filename of about 40 chars */
2694                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2695                         out_of_space = True;
2696                         finished = False;
2697                 } else {
2698                         ntstatus = get_lanman2_dir_entry(ctx,
2699                                         conn,
2700                                         dirptr,
2701                                         req->flags2,
2702                                         mask,dirtype,info_level,
2703                                         requires_resume_key,dont_descend,
2704                                         ask_sharemode,
2705                                         &p,pdata,data_end,
2706                                         space_remaining,
2707                                         &got_exact_match,
2708                                         &last_entry_off, ea_list);
2709                         if (NT_STATUS_EQUAL(ntstatus,
2710                                         NT_STATUS_ILLEGAL_CHARACTER)) {
2711                                 /*
2712                                  * Bad character conversion on name. Ignore this
2713                                  * entry.
2714                                  */
2715                                 continue;
2716                         }
2717                         if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
2718                                 out_of_space = true;
2719                         } else {
2720                                 finished = !NT_STATUS_IS_OK(ntstatus);
2721                         }
2722                 }
2723
2724                 if (!finished && !out_of_space)
2725                         numentries++;
2726
2727                 /*
2728                  * As an optimisation if we know we aren't looking
2729                  * for a wildcard name (ie. the name matches the wildcard exactly)
2730                  * then we can finish on any (first) match.
2731                  * This speeds up large directory searches. JRA.
2732                  */
2733
2734                 if(got_exact_match)
2735                         finished = True;
2736
2737                 /* Ensure space_remaining never goes -ve. */
2738                 if (PTR_DIFF(p,pdata) > max_data_bytes) {
2739                         space_remaining = 0;
2740                         out_of_space = true;
2741                 } else {
2742                         space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2743                 }
2744         }
2745
2746         /* Check if we can close the dirptr */
2747         if(close_after_first || (finished && close_if_end)) {
2748                 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
2749                 dptr_close(sconn, &dptr_num);
2750         }
2751
2752         /*
2753          * If there are no matching entries we must return ERRDOS/ERRbadfile -
2754          * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2755          * the protocol level is less than NT1. Tested with smbclient. JRA.
2756          * This should fix the OS/2 client bug #2335.
2757          */
2758
2759         if(numentries == 0) {
2760                 dptr_close(sconn, &dptr_num);
2761                 if (get_Protocol() < PROTOCOL_NT1) {
2762                         reply_force_doserror(req, ERRDOS, ERRnofiles);
2763                         goto out;
2764                 } else {
2765                         reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
2766                                         ERRDOS, ERRbadfile);
2767                         goto out;
2768                 }
2769         }
2770
2771         /* At this point pdata points to numentries directory entries. */
2772
2773         /* Set up the return parameter block */
2774         SSVAL(params,0,dptr_num);
2775         SSVAL(params,2,numentries);
2776         SSVAL(params,4,finished);
2777         SSVAL(params,6,0); /* Never an EA error */
2778         SSVAL(params,8,last_entry_off);
2779
2780         send_trans2_replies(conn, req, NT_STATUS_OK, params, 10, pdata, PTR_DIFF(p,pdata),
2781                             max_data_bytes);
2782
2783         if ((! *directory) && dptr_path(sconn, dptr_num)) {
2784                 directory = talloc_strdup(talloc_tos(),dptr_path(sconn, dptr_num));
2785                 if (!directory) {
2786                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2787                 }
2788         }
2789
2790         DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2791                 smb_fn_name(req->cmd),
2792                 mask, directory, dirtype, numentries ) );
2793
2794         /*
2795          * Force a name mangle here to ensure that the
2796          * mask as an 8.3 name is top of the mangled cache.
2797          * The reasons for this are subtle. Don't remove
2798          * this code unless you know what you are doing
2799          * (see PR#13758). JRA.
2800          */
2801
2802         if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
2803                 char mangled_name[13];
2804                 name_to_8_3(mask, mangled_name, True, conn->params);
2805         }
2806  out:
2807
2808         if (backup_priv) {
2809                 unbecome_root();
2810         }
2811
2812         TALLOC_FREE(smb_dname);
2813         return;
2814 }
2815
2816 /****************************************************************************
2817  Reply to a TRANS2_FINDNEXT.
2818 ****************************************************************************/
2819
2820 static void call_trans2findnext(connection_struct *conn,
2821                                 struct smb_request *req,
2822                                 char **pparams, int total_params,
2823                                 char **ppdata, int total_data,
2824                                 unsigned int max_data_bytes)
2825 {
2826         /* We must be careful here that we don't return more than the
2827                 allowed number of data bytes. If this means returning fewer than
2828                 maxentries then so be it. We assume that the redirector has
2829                 enough room for the fixed number of parameter bytes it has
2830                 requested. */
2831         char *params = *pparams;
2832         char *pdata = *ppdata;
2833         char *data_end;
2834         int dptr_num;
2835         int maxentries;
2836         uint16 info_level;
2837         uint32 resume_key;
2838         uint16 findnext_flags;
2839         bool close_after_request;
2840         bool close_if_end;
2841         bool requires_resume_key;
2842         bool continue_bit;
2843         bool mask_contains_wcard = False;
2844         char *resume_name = NULL;
2845         const char *mask = NULL;
2846         const char *directory = NULL;
2847         char *p = NULL;
2848         uint16 dirtype;
2849         int numentries = 0;
2850         int i, last_entry_off=0;
2851         bool finished = False;
2852         bool dont_descend = False;
2853         bool out_of_space = False;
2854         int space_remaining;
2855         struct ea_list *ea_list = NULL;
2856         NTSTATUS ntstatus = NT_STATUS_OK;
2857         bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2858         TALLOC_CTX *ctx = talloc_tos();
2859         struct dptr_struct *dirptr;
2860         struct smbd_server_connection *sconn = req->sconn;
2861         bool backup_priv = false; 
2862
2863         if (total_params < 13) {
2864                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2865                 return;
2866         }
2867
2868         dptr_num = SVAL(params,0);
2869         maxentries = SVAL(params,2);
2870         info_level = SVAL(params,4);
2871         resume_key = IVAL(params,6);
2872         findnext_flags = SVAL(params,10);
2873         close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
2874         close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2875         requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2876         continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
2877
2878         if (!continue_bit) {
2879                 /* We only need resume_name if continue_bit is zero. */
2880                 srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
2881                               params+12,
2882                               total_params - 12, STR_TERMINATE, &ntstatus,
2883                               &mask_contains_wcard);
2884                 if (!NT_STATUS_IS_OK(ntstatus)) {
2885                         /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2886                            complain (it thinks we're asking for the directory above the shared
2887                            path or an invalid name). Catch this as the resume name is only compared, never used in
2888                            a file access. JRA. */
2889                         srvstr_pull_talloc(ctx, params, req->flags2,
2890                                 &resume_name, params+12,
2891                                 total_params - 12,
2892                                 STR_TERMINATE);
2893
2894                         if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
2895                                 reply_nterror(req, ntstatus);
2896                                 return;
2897                         }
2898                 }
2899         }
2900
2901         DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2902 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2903 resume_key = %d resume name = %s continue=%d level = %d\n",
2904                 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end, 
2905                 requires_resume_key, resume_key,
2906                 resume_name ? resume_name : "(NULL)", continue_bit, info_level));
2907
2908         if (!maxentries) {
2909                 /* W2K3 seems to treat zero as 1. */
2910                 maxentries = 1;
2911         }
2912
2913         switch (info_level) {
2914                 case SMB_FIND_INFO_STANDARD:
2915                 case SMB_FIND_EA_SIZE:
2916                 case SMB_FIND_EA_LIST:
2917                 case SMB_FIND_FILE_DIRECTORY_INFO:
2918                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2919                 case SMB_FIND_FILE_NAMES_INFO:
2920                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2921                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2922                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2923                         break;
2924                 case SMB_FIND_FILE_UNIX:
2925                 case SMB_FIND_FILE_UNIX_INFO2:
2926                         /* Always use filesystem for UNIX mtime query. */
2927                         ask_sharemode = false;
2928                         if (!lp_unix_extensions()) {
2929                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2930                                 return;
2931                         }
2932                         break;
2933                 default:
2934                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2935                         return;
2936         }
2937
2938         if (info_level == SMB_FIND_EA_LIST) {
2939                 uint32 ea_size;
2940
2941                 if (total_data < 4) {
2942                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2943                         return;
2944                 }
2945
2946                 ea_size = IVAL(pdata,0);
2947                 if (ea_size != total_data) {
2948                         DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2949 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2950                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2951                         return;
2952                 }
2953
2954                 if (!lp_ea_support(SNUM(conn))) {
2955                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
2956                         return;
2957                 }
2958
2959                 /* Pull out the list of names. */
2960                 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2961                 if (!ea_list) {
2962                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2963                         return;
2964                 }
2965         }
2966
2967         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
2968                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2969                 return;
2970         }
2971
2972         *ppdata = (char *)SMB_REALLOC(
2973                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2974         if(*ppdata == NULL) {
2975                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2976                 return;
2977         }
2978
2979         pdata = *ppdata;
2980         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2981
2982         /* Realloc the params space */
2983         *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
2984         if(*pparams == NULL ) {
2985                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2986                 return;
2987         }
2988
2989         params = *pparams;
2990
2991         /* Check that the dptr is valid */
2992         if(!(dirptr = dptr_fetch_lanman2(sconn, dptr_num))) {
2993                 reply_nterror(req, STATUS_NO_MORE_FILES);
2994                 return;
2995         }
2996
2997         directory = dptr_path(sconn, dptr_num);
2998
2999         /* Get the wildcard mask from the dptr */
3000         if((mask = dptr_wcard(sconn, dptr_num))== NULL) {
3001                 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
3002                 reply_nterror(req, STATUS_NO_MORE_FILES);
3003                 return;
3004         }
3005
3006         /* Get the attr mask from the dptr */
3007         dirtype = dptr_attr(sconn, dptr_num);
3008
3009         backup_priv = dptr_get_priv(dirptr);
3010
3011         DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld) "
3012                 "backup_priv = %d\n",
3013                 dptr_num, mask, dirtype,
3014                 (long)dirptr,
3015                 dptr_TellDir(dirptr),
3016                 (int)backup_priv));
3017
3018         /* Initialize per TRANS2_FIND_NEXT operation data */
3019         dptr_init_search_op(dirptr);
3020
3021         /* We don't need to check for VOL here as this is returned by
3022                 a different TRANS2 call. */
3023
3024         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
3025                  directory,lp_dont_descend(ctx, SNUM(conn))));
3026         if (in_list(directory,lp_dont_descend(ctx, SNUM(conn)),conn->case_sensitive))
3027                 dont_descend = True;
3028
3029         p = pdata;
3030         space_remaining = max_data_bytes;
3031         out_of_space = False;
3032
3033         if (backup_priv) {
3034                 become_root();
3035         }
3036
3037         /*
3038          * Seek to the correct position. We no longer use the resume key but
3039          * depend on the last file name instead.
3040          */
3041
3042         if(!continue_bit && resume_name && *resume_name) {
3043                 SMB_STRUCT_STAT st;
3044
3045                 long current_pos = 0;
3046                 /*
3047                  * Remember, name_to_8_3 is called by
3048                  * get_lanman2_dir_entry(), so the resume name
3049                  * could be mangled. Ensure we check the unmangled name.
3050                  */
3051
3052                 if (mangle_is_mangled(resume_name, conn->params)) {
3053                         char *new_resume_name = NULL;
3054                         mangle_lookup_name_from_8_3(ctx,
3055                                                 resume_name,
3056                                                 &new_resume_name,
3057                                                 conn->params);
3058                         if (new_resume_name) {
3059                                 resume_name = new_resume_name;
3060                         }
3061                 }
3062
3063                 /*
3064                  * Fix for NT redirector problem triggered by resume key indexes
3065                  * changing between directory scans. We now return a resume key of 0
3066                  * and instead look for the filename to continue from (also given
3067                  * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
3068                  * findfirst/findnext (as is usual) then the directory pointer
3069                  * should already be at the correct place.
3070                  */
3071
3072                 finished = !dptr_SearchDir(dirptr, resume_name, &current_pos, &st);
3073         } /* end if resume_name && !continue_bit */
3074
3075         for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
3076                 bool got_exact_match = False;
3077
3078                 /* this is a heuristic to avoid seeking the dirptr except when 
3079                         absolutely necessary. It allows for a filename of about 40 chars */
3080                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
3081                         out_of_space = True;
3082                         finished = False;
3083                 } else {
3084                         ntstatus = get_lanman2_dir_entry(ctx,
3085                                                 conn,
3086                                                 dirptr,
3087                                                 req->flags2,
3088                                                 mask,dirtype,info_level,
3089                                                 requires_resume_key,dont_descend,
3090                                                 ask_sharemode,
3091                                                 &p,pdata,data_end,
3092                                                 space_remaining,
3093                                                 &got_exact_match,
3094                                                 &last_entry_off, ea_list);
3095                         if (NT_STATUS_EQUAL(ntstatus,
3096                                         NT_STATUS_ILLEGAL_CHARACTER)) {
3097                                 /*
3098                                  * Bad character conversion on name. Ignore this
3099                                  * entry.
3100                                  */
3101                                 continue;
3102                         }
3103                         if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
3104                                 out_of_space = true;
3105                         } else {
3106                                 finished = !NT_STATUS_IS_OK(ntstatus);
3107                         }
3108                 }
3109
3110                 if (!finished && !out_of_space)
3111                         numentries++;
3112
3113                 /*
3114                  * As an optimisation if we know we aren't looking
3115                  * for a wildcard name (ie. the name matches the wildcard exactly)
3116                  * then we can finish on any (first) match.
3117                  * This speeds up large directory searches. JRA.
3118                  */
3119
3120                 if(got_exact_match)
3121                         finished = True;
3122
3123                 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
3124         }
3125
3126         DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
3127                 smb_fn_name(req->cmd),
3128                 mask, directory, dirtype, numentries ) );
3129
3130         /* Check if we can close the dirptr */
3131         if(close_after_request || (finished && close_if_end)) {
3132                 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
3133                 dptr_close(sconn, &dptr_num); /* This frees up the saved mask */
3134         }
3135
3136         if (backup_priv) {
3137                 unbecome_root();
3138         }
3139
3140         /* Set up the return parameter block */
3141         SSVAL(params,0,numentries);
3142         SSVAL(params,2,finished);
3143         SSVAL(params,4,0); /* Never an EA error */
3144         SSVAL(params,6,last_entry_off);
3145
3146         send_trans2_replies(conn, req, NT_STATUS_OK, params, 8, pdata, PTR_DIFF(p,pdata),
3147                             max_data_bytes);
3148
3149         return;
3150 }
3151
3152 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
3153 {
3154         E_md4hash(lp_servicename(talloc_tos(), SNUM(conn)),objid);
3155         return objid;
3156 }
3157
3158 static void samba_extended_info_version(struct smb_extended_info *extended_info)
3159 {
3160         SMB_ASSERT(extended_info != NULL);
3161
3162         extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
3163         extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
3164                                        | ((SAMBA_VERSION_MINOR & 0xff) << 16)
3165                                        | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
3166 #ifdef SAMBA_VERSION_REVISION
3167         extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
3168 #endif
3169         extended_info->samba_subversion = 0;
3170 #ifdef SAMBA_VERSION_RC_RELEASE
3171         extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
3172 #else
3173 #ifdef SAMBA_VERSION_PRE_RELEASE
3174         extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
3175 #endif
3176 #endif
3177 #ifdef SAMBA_VERSION_VENDOR_PATCH
3178         extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
3179 #endif
3180         extended_info->samba_gitcommitdate = 0;
3181 #ifdef SAMBA_VERSION_COMMIT_TIME
3182         unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_COMMIT_TIME);
3183 #endif
3184
3185         memset(extended_info->samba_version_string, 0,
3186                sizeof(extended_info->samba_version_string));
3187
3188         snprintf (extended_info->samba_version_string,
3189                   sizeof(extended_info->samba_version_string),
3190                   "%s", samba_version_string());
3191 }
3192
3193 NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
3194                          connection_struct *conn,
3195                          TALLOC_CTX *mem_ctx,
3196                          uint16_t info_level,
3197                          uint16_t flags2,
3198                          unsigned int max_data_bytes,
3199                          size_t *fixed_portion,
3200                          struct smb_filename *fname,
3201                          char **ppdata,
3202                          int *ret_data_len)
3203 {
3204         char *pdata, *end_data;
3205         int data_len = 0;
3206         size_t len = 0;
3207         const char *vname = volume_label(talloc_tos(), SNUM(conn));
3208         int snum = SNUM(conn);
3209         const char *fstype = lp_fstype(SNUM(conn));
3210         const char *filename = NULL;
3211         uint32 additional_flags = 0;
3212         struct smb_filename smb_fname;
3213         SMB_STRUCT_STAT st;
3214         NTSTATUS status = NT_STATUS_OK;
3215         uint64_t df_ret;
3216
3217         if (fname == NULL || fname->base_name == NULL) {
3218                 filename = ".";
3219         } else {
3220                 filename = fname->base_name;
3221         }
3222
3223         if (IS_IPC(conn)) {
3224                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
3225                         DEBUG(0,("smbd_do_qfsinfo: not an allowed "
3226                                 "info level (0x%x) on IPC$.\n",
3227                                 (unsigned int)info_level));
3228                         return NT_STATUS_ACCESS_DENIED;
3229                 }
3230         }
3231
3232         DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
3233
3234         ZERO_STRUCT(smb_fname);
3235         smb_fname.base_name = discard_const_p(char, filename);
3236
3237         if(SMB_VFS_STAT(conn, &smb_fname) != 0) {
3238                 DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
3239                 return map_nt_error_from_unix(errno);
3240         }
3241
3242         st = smb_fname.st;
3243
3244         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
3245                 return NT_STATUS_INVALID_PARAMETER;
3246         }
3247
3248         *ppdata = (char *)SMB_REALLOC(
3249                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
3250         if (*ppdata == NULL) {
3251                 return NT_STATUS_NO_MEMORY;
3252         }
3253
3254         pdata = *ppdata;
3255         memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
3256         end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
3257
3258         *fixed_portion = 0;
3259
3260         switch (info_level) {
3261                 case SMB_INFO_ALLOCATION:
3262                 {
3263                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
3264                         data_len = 18;
3265                         df_ret = get_dfree_info(conn, filename, &bsize, &dfree,
3266                                                 &dsize);
3267                         if (df_ret == (uint64_t)-1) {
3268                                 return map_nt_error_from_unix(errno);
3269                         }
3270
3271                         block_size = lp_block_size(snum);
3272                         if (bsize < block_size) {
3273                                 uint64_t factor = block_size/bsize;
3274                                 bsize = block_size;
3275                                 dsize /= factor;
3276                                 dfree /= factor;
3277                         }
3278                         if (bsize > block_size) {
3279                                 uint64_t factor = bsize/block_size;
3280                                 bsize = block_size;
3281                                 dsize *= factor;
3282                                 dfree *= factor;
3283                         }
3284                         bytes_per_sector = 512;
3285                         sectors_per_unit = bsize/bytes_per_sector;
3286
3287                         DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
3288 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
3289                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
3290
3291                         SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
3292                         SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
3293                         SIVAL(pdata,l1_cUnit,dsize);
3294                         SIVAL(pdata,l1_cUnitAvail,dfree);
3295                         SSVAL(pdata,l1_cbSector,bytes_per_sector);
3296                         break;
3297                 }
3298
3299                 case SMB_INFO_VOLUME:
3300                         /* Return volume name */
3301                         /* 
3302                          * Add volume serial number - hash of a combination of
3303                          * the called hostname and the service name.
3304                          */
3305                         SIVAL(pdata,0,str_checksum(lp_servicename(talloc_tos(), snum)) ^ (str_checksum(get_local_machine_name())<<16) );
3306                         /*
3307                          * Win2k3 and previous mess this up by sending a name length
3308                          * one byte short. I believe only older clients (OS/2 Win9x) use
3309                          * this call so try fixing this by adding a terminating null to
3310                          * the pushed string. The change here was adding the STR_TERMINATE. JRA.