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