06536f9e217765e2925f8e6d735da60857280197
[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         NTSTATUS status;
475
476         if (!lp_ea_support(SNUM(conn))) {
477                 return NT_STATUS_EAS_NOT_SUPPORTED;
478         }
479
480         status = get_full_smb_filename(talloc_tos(), smb_fname,
481                                        &fname);
482         if (!NT_STATUS_IS_OK(status)) {
483                 return status;
484         }
485
486         for (;ea_list; ea_list = ea_list->next) {
487                 int ret;
488                 fstring unix_ea_name;
489
490                 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
491                 fstrcat(unix_ea_name, ea_list->ea.name);
492
493                 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
494
495                 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
496
497                 if (samba_private_attr_name(unix_ea_name)) {
498                         DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
499                         return NT_STATUS_ACCESS_DENIED;
500                 }
501
502                 if (ea_list->ea.value.length == 0) {
503                         /* Remove the attribute. */
504                         if (fsp && (fsp->fh->fd != -1)) {
505                                 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
506                                         unix_ea_name, fsp->fsp_name));
507                                 ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
508                         } else {
509                                 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
510                                         unix_ea_name, fname));
511                                 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
512                         }
513 #ifdef ENOATTR
514                         /* Removing a non existent attribute always succeeds. */
515                         if (ret == -1 && errno == ENOATTR) {
516                                 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
517                                                 unix_ea_name));
518                                 ret = 0;
519                         }
520 #endif
521                 } else {
522                         if (fsp && (fsp->fh->fd != -1)) {
523                                 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
524                                         unix_ea_name, fsp->fsp_name));
525                                 ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
526                                                         ea_list->ea.value.data, ea_list->ea.value.length, 0);
527                         } else {
528                                 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
529                                         unix_ea_name, fname));
530                                 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
531                                                         ea_list->ea.value.data, ea_list->ea.value.length, 0);
532                         }
533                 }
534
535                 if (ret == -1) {
536 #ifdef ENOTSUP
537                         if (errno == ENOTSUP) {
538                                 return NT_STATUS_EAS_NOT_SUPPORTED;
539                         }
540 #endif
541                         return map_nt_error_from_unix(errno);
542                 }
543
544         }
545         return NT_STATUS_OK;
546 }
547 /****************************************************************************
548  Read a list of EA names from an incoming data buffer. Create an ea_list with them.
549 ****************************************************************************/
550
551 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
552 {
553         struct ea_list *ea_list_head = NULL;
554         size_t converted_size, offset = 0;
555
556         while (offset + 2 < data_size) {
557                 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
558                 unsigned int namelen = CVAL(pdata,offset);
559
560                 offset++; /* Go past the namelen byte. */
561
562                 /* integer wrap paranioa. */
563                 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
564                                 (offset > data_size) || (namelen > data_size) ||
565                                 (offset + namelen >= data_size)) {
566                         break;
567                 }
568                 /* Ensure the name is null terminated. */
569                 if (pdata[offset + namelen] != '\0') {
570                         return NULL;
571                 }
572                 if (!pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset],
573                                        &converted_size)) {
574                         DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
575                                  "failed: %s", strerror(errno)));
576                 }
577                 if (!eal->ea.name) {
578                         return NULL;
579                 }
580
581                 offset += (namelen + 1); /* Go past the name + terminating zero. */
582                 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
583                 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
584         }
585
586         return ea_list_head;
587 }
588
589 /****************************************************************************
590  Read one EA list entry from the buffer.
591 ****************************************************************************/
592
593 struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
594 {
595         struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
596         uint16 val_len;
597         unsigned int namelen;
598         size_t converted_size;
599
600         if (!eal) {
601                 return NULL;
602         }
603
604         if (data_size < 6) {
605                 return NULL;
606         }
607
608         eal->ea.flags = CVAL(pdata,0);
609         namelen = CVAL(pdata,1);
610         val_len = SVAL(pdata,2);
611
612         if (4 + namelen + 1 + val_len > data_size) {
613                 return NULL;
614         }
615
616         /* Ensure the name is null terminated. */
617         if (pdata[namelen + 4] != '\0') {
618                 return NULL;
619         }
620         if (!pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4, &converted_size)) {
621                 DEBUG(0,("read_ea_list_entry: pull_ascii_talloc failed: %s",
622                          strerror(errno)));
623         }
624         if (!eal->ea.name) {
625                 return NULL;
626         }
627
628         eal->ea.value = data_blob_talloc(eal, NULL, (size_t)val_len + 1);
629         if (!eal->ea.value.data) {
630                 return NULL;
631         }
632
633         memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
634
635         /* Ensure we're null terminated just in case we print the value. */
636         eal->ea.value.data[val_len] = '\0';
637         /* But don't count the null. */
638         eal->ea.value.length--;
639
640         if (pbytes_used) {
641                 *pbytes_used = 4 + namelen + 1 + val_len;
642         }
643
644         DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
645         dump_data(10, eal->ea.value.data, eal->ea.value.length);
646
647         return eal;
648 }
649
650 /****************************************************************************
651  Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
652 ****************************************************************************/
653
654 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
655 {
656         struct ea_list *ea_list_head = NULL;
657         size_t offset = 0;
658         size_t bytes_used = 0;
659
660         while (offset < data_size) {
661                 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
662
663                 if (!eal) {
664                         return NULL;
665                 }
666
667                 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
668                 offset += bytes_used;
669         }
670
671         return ea_list_head;
672 }
673
674 /****************************************************************************
675  Count the total EA size needed.
676 ****************************************************************************/
677
678 static size_t ea_list_size(struct ea_list *ealist)
679 {
680         fstring dos_ea_name;
681         struct ea_list *listp;
682         size_t ret = 0;
683
684         for (listp = ealist; listp; listp = listp->next) {
685                 push_ascii_fstring(dos_ea_name, listp->ea.name);
686                 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
687         }
688         /* Add on 4 for total length. */
689         if (ret) {
690                 ret += 4;
691         }
692
693         return ret;
694 }
695
696 /****************************************************************************
697  Return a union of EA's from a file list and a list of names.
698  The TALLOC context for the two lists *MUST* be identical as we steal
699  memory from one list to add to another. JRA.
700 ****************************************************************************/
701
702 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
703 {
704         struct ea_list *nlistp, *flistp;
705
706         for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
707                 for (flistp = file_list; flistp; flistp = flistp->next) {
708                         if (strequal(nlistp->ea.name, flistp->ea.name)) {
709                                 break;
710                         }
711                 }
712
713                 if (flistp) {
714                         /* Copy the data from this entry. */
715                         nlistp->ea.flags = flistp->ea.flags;
716                         nlistp->ea.value = flistp->ea.value;
717                 } else {
718                         /* Null entry. */
719                         nlistp->ea.flags = 0;
720                         ZERO_STRUCT(nlistp->ea.value);
721                 }
722         }
723
724         *total_ea_len = ea_list_size(name_list);
725         return name_list;
726 }
727
728 /****************************************************************************
729   Send the required number of replies back.
730   We assume all fields other than the data fields are
731   set correctly for the type of call.
732   HACK ! Always assumes smb_setup field is zero.
733 ****************************************************************************/
734
735 void send_trans2_replies(connection_struct *conn,
736                         struct smb_request *req,
737                          const char *params,
738                          int paramsize,
739                          const char *pdata,
740                          int datasize,
741                          int max_data_bytes)
742 {
743         /* As we are using a protocol > LANMAN1 then the max_send
744          variable must have been set in the sessetupX call.
745          This takes precedence over the max_xmit field in the
746          global struct. These different max_xmit variables should
747          be merged as this is now too confusing */
748
749         int data_to_send = datasize;
750         int params_to_send = paramsize;
751         int useable_space;
752         const char *pp = params;
753         const char *pd = pdata;
754         int params_sent_thistime, data_sent_thistime, total_sent_thistime;
755         int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
756         int data_alignment_offset = 0;
757         bool overflow = False;
758         struct smbd_server_connection *sconn = smbd_server_conn;
759         int max_send = sconn->smb1.sessions.max_send;
760
761         /* Modify the data_to_send and datasize and set the error if
762            we're trying to send more than max_data_bytes. We still send
763            the part of the packet(s) that fit. Strange, but needed
764            for OS/2. */
765
766         if (max_data_bytes > 0 && datasize > max_data_bytes) {
767                 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
768                         max_data_bytes, datasize ));
769                 datasize = data_to_send = max_data_bytes;
770                 overflow = True;
771         }
772
773         /* If there genuinely are no parameters or data to send just send the empty packet */
774
775         if(params_to_send == 0 && data_to_send == 0) {
776                 reply_outbuf(req, 10, 0);
777                 show_msg((char *)req->outbuf);
778                 if (!srv_send_smb(smbd_server_fd(),
779                                 (char *)req->outbuf,
780                                 true, req->seqnum+1,
781                                 IS_CONN_ENCRYPTED(conn),
782                                 &req->pcd)) {
783                         exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
784                 }
785                 TALLOC_FREE(req->outbuf);
786                 return;
787         }
788
789         /* When sending params and data ensure that both are nicely aligned */
790         /* Only do this alignment when there is also data to send - else
791                 can cause NT redirector problems. */
792
793         if (((params_to_send % 4) != 0) && (data_to_send != 0))
794                 data_alignment_offset = 4 - (params_to_send % 4);
795
796         /* Space is bufsize minus Netbios over TCP header minus SMB header */
797         /* The alignment_offset is to align the param bytes on an even byte
798                 boundary. NT 4.0 Beta needs this to work correctly. */
799
800         useable_space = max_send - (smb_size
801                                     + 2 * 10 /* wct */
802                                     + alignment_offset
803                                     + data_alignment_offset);
804
805         if (useable_space < 0) {
806                 DEBUG(0, ("send_trans2_replies failed sanity useable_space "
807                           "= %d!!!", useable_space));
808                 exit_server_cleanly("send_trans2_replies: Not enough space");
809         }
810
811         while (params_to_send || data_to_send) {
812                 /* Calculate whether we will totally or partially fill this packet */
813
814                 total_sent_thistime = params_to_send + data_to_send;
815
816                 /* We can never send more than useable_space */
817                 /*
818                  * Note that 'useable_space' does not include the alignment offsets,
819                  * but we must include the alignment offsets in the calculation of
820                  * the length of the data we send over the wire, as the alignment offsets
821                  * are sent here. Fix from Marc_Jacobsen@hp.com.
822                  */
823
824                 total_sent_thistime = MIN(total_sent_thistime, useable_space);
825
826                 reply_outbuf(req, 10, total_sent_thistime + alignment_offset
827                              + data_alignment_offset);
828
829                 /*
830                  * We might have SMBtrans2s in req which was transferred to
831                  * the outbuf, fix that.
832                  */
833                 SCVAL(req->outbuf, smb_com, SMBtrans2);
834
835                 /* Set total params and data to be sent */
836                 SSVAL(req->outbuf,smb_tprcnt,paramsize);
837                 SSVAL(req->outbuf,smb_tdrcnt,datasize);
838
839                 /* Calculate how many parameters and data we can fit into
840                  * this packet. Parameters get precedence
841                  */
842
843                 params_sent_thistime = MIN(params_to_send,useable_space);
844                 data_sent_thistime = useable_space - params_sent_thistime;
845                 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
846
847                 SSVAL(req->outbuf,smb_prcnt, params_sent_thistime);
848
849                 /* smb_proff is the offset from the start of the SMB header to the
850                         parameter bytes, however the first 4 bytes of outbuf are
851                         the Netbios over TCP header. Thus use smb_base() to subtract
852                         them from the calculation */
853
854                 SSVAL(req->outbuf,smb_proff,
855                       ((smb_buf(req->outbuf)+alignment_offset)
856                        - smb_base(req->outbuf)));
857
858                 if(params_sent_thistime == 0)
859                         SSVAL(req->outbuf,smb_prdisp,0);
860                 else
861                         /* Absolute displacement of param bytes sent in this packet */
862                         SSVAL(req->outbuf,smb_prdisp,pp - params);
863
864                 SSVAL(req->outbuf,smb_drcnt, data_sent_thistime);
865                 if(data_sent_thistime == 0) {
866                         SSVAL(req->outbuf,smb_droff,0);
867                         SSVAL(req->outbuf,smb_drdisp, 0);
868                 } else {
869                         /* The offset of the data bytes is the offset of the
870                                 parameter bytes plus the number of parameters being sent this time */
871                         SSVAL(req->outbuf, smb_droff,
872                               ((smb_buf(req->outbuf)+alignment_offset)
873                                - smb_base(req->outbuf))
874                               + params_sent_thistime + data_alignment_offset);
875                         SSVAL(req->outbuf,smb_drdisp, pd - pdata);
876                 }
877
878                 /* Initialize the padding for alignment */
879
880                 if (alignment_offset != 0) {
881                         memset(smb_buf(req->outbuf), 0, alignment_offset);
882                 }
883
884                 /* Copy the param bytes into the packet */
885
886                 if(params_sent_thistime) {
887                         memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
888                                params_sent_thistime);
889                 }
890
891                 /* Copy in the data bytes */
892                 if(data_sent_thistime) {
893                         if (data_alignment_offset != 0) {
894                                 memset((smb_buf(req->outbuf)+alignment_offset+
895                                         params_sent_thistime), 0,
896                                        data_alignment_offset);
897                         }
898                         memcpy(smb_buf(req->outbuf)+alignment_offset
899                                +params_sent_thistime+data_alignment_offset,
900                                pd,data_sent_thistime);
901                 }
902
903                 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
904                         params_sent_thistime, data_sent_thistime, useable_space));
905                 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
906                         params_to_send, data_to_send, paramsize, datasize));
907
908                 if (overflow) {
909                         error_packet_set((char *)req->outbuf,
910                                          ERRDOS,ERRbufferoverflow,
911                                          STATUS_BUFFER_OVERFLOW,
912                                          __LINE__,__FILE__);
913                 }
914
915                 /* Send the packet */
916                 show_msg((char *)req->outbuf);
917                 if (!srv_send_smb(smbd_server_fd(),
918                                 (char *)req->outbuf,
919                                 true, req->seqnum+1,
920                                 IS_CONN_ENCRYPTED(conn),
921                                 &req->pcd))
922                         exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
923
924                 TALLOC_FREE(req->outbuf);
925
926                 pp += params_sent_thistime;
927                 pd += data_sent_thistime;
928
929                 params_to_send -= params_sent_thistime;
930                 data_to_send -= data_sent_thistime;
931
932                 /* Sanity check */
933                 if(params_to_send < 0 || data_to_send < 0) {
934                         DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
935                                 params_to_send, data_to_send));
936                         return;
937                 }
938         }
939
940         return;
941 }
942
943 /****************************************************************************
944  Reply to a TRANSACT2_OPEN.
945 ****************************************************************************/
946
947 static void call_trans2open(connection_struct *conn,
948                             struct smb_request *req,
949                             char **pparams, int total_params,
950                             char **ppdata, int total_data,
951                             unsigned int max_data_bytes)
952 {
953         struct smb_filename *smb_fname = NULL;
954         char *params = *pparams;
955         char *pdata = *ppdata;
956         int deny_mode;
957         int32 open_attr;
958         bool oplock_request;
959 #if 0
960         bool return_additional_info;
961         int16 open_sattr;
962         time_t open_time;
963 #endif
964         int open_ofun;
965         uint32 open_size;
966         char *pname;
967         char *fname = NULL;
968         SMB_OFF_T size=0;
969         int fattr=0,mtime=0;
970         SMB_INO_T inode = 0;
971         int smb_action = 0;
972         files_struct *fsp;
973         struct ea_list *ea_list = NULL;
974         uint16 flags = 0;
975         NTSTATUS status;
976         uint32 access_mask;
977         uint32 share_mode;
978         uint32 create_disposition;
979         uint32 create_options = 0;
980         TALLOC_CTX *ctx = talloc_tos();
981
982         /*
983          * Ensure we have enough parameters to perform the operation.
984          */
985
986         if (total_params < 29) {
987                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
988                 goto out;
989         }
990
991         flags = SVAL(params, 0);
992         deny_mode = SVAL(params, 2);
993         open_attr = SVAL(params,6);
994         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
995         if (oplock_request) {
996                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
997         }
998
999 #if 0
1000         return_additional_info = BITSETW(params,0);
1001         open_sattr = SVAL(params, 4);
1002         open_time = make_unix_date3(params+8);
1003 #endif
1004         open_ofun = SVAL(params,12);
1005         open_size = IVAL(params,14);
1006         pname = &params[28];
1007
1008         if (IS_IPC(conn)) {
1009                 reply_doserror(req, ERRSRV, ERRaccess);
1010                 goto out;
1011         }
1012
1013         srvstr_get_path(ctx, params, req->flags2, &fname, pname,
1014                         total_params - 28, STR_TERMINATE,
1015                         &status);
1016         if (!NT_STATUS_IS_OK(status)) {
1017                 reply_nterror(req, status);
1018                 goto out;
1019         }
1020
1021         DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
1022                 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
1023                 (unsigned int)open_ofun, open_size));
1024
1025         status = filename_convert(ctx,
1026                                 conn,
1027                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
1028                                 fname,
1029                                 &smb_fname,
1030                                 NULL);
1031         if (!NT_STATUS_IS_OK(status)) {
1032                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1033                         reply_botherror(req,
1034                                 NT_STATUS_PATH_NOT_COVERED,
1035                                 ERRSRV, ERRbadpath);
1036                         goto out;
1037                 }
1038                 reply_nterror(req, status);
1039                 goto out;
1040         }
1041
1042         if (open_ofun == 0) {
1043                 reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
1044                 goto out;
1045         }
1046
1047         if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
1048                                 open_ofun,
1049                                 &access_mask,
1050                                 &share_mode,
1051                                 &create_disposition,
1052                                 &create_options)) {
1053                 reply_doserror(req, ERRDOS, ERRbadaccess);
1054                 goto out;
1055         }
1056
1057         /* Any data in this call is an EA list. */
1058         if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
1059                 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1060                 goto out;
1061         }
1062
1063         if (total_data != 4) {
1064                 if (total_data < 10) {
1065                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1066                         goto out;
1067                 }
1068
1069                 if (IVAL(pdata,0) > total_data) {
1070                         DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
1071                                 IVAL(pdata,0), (unsigned int)total_data));
1072                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1073                         goto out;
1074                 }
1075
1076                 ea_list = read_ea_list(talloc_tos(), pdata + 4,
1077                                        total_data - 4);
1078                 if (!ea_list) {
1079                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1080                         goto out;
1081                 }
1082         } else if (IVAL(pdata,0) != 4) {
1083                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1084                 goto out;
1085         }
1086
1087         status = SMB_VFS_CREATE_FILE(
1088                 conn,                                   /* conn */
1089                 req,                                    /* req */
1090                 0,                                      /* root_dir_fid */
1091                 smb_fname,                              /* fname */
1092                 access_mask,                            /* access_mask */
1093                 share_mode,                             /* share_access */
1094                 create_disposition,                     /* create_disposition*/
1095                 create_options,                         /* create_options */
1096                 open_attr,                              /* file_attributes */
1097                 oplock_request,                         /* oplock_request */
1098                 open_size,                              /* allocation_size */
1099                 NULL,                                   /* sd */
1100                 ea_list,                                /* ea_list */
1101                 &fsp,                                   /* result */
1102                 &smb_action);                           /* psbuf */
1103
1104         if (!NT_STATUS_IS_OK(status)) {
1105                 if (open_was_deferred(req->mid)) {
1106                         /* We have re-scheduled this call. */
1107                         goto out;
1108                 }
1109                 reply_openerror(req, status);
1110                 goto out;
1111         }
1112
1113         size = get_file_size_stat(&smb_fname->st);
1114         fattr = dos_mode(conn, smb_fname);
1115         mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1116         inode = smb_fname->st.st_ex_ino;
1117         if (fattr & aDIR) {
1118                 close_file(req, fsp, ERROR_CLOSE);
1119                 reply_doserror(req, ERRDOS,ERRnoaccess);
1120                 goto out;
1121         }
1122
1123         /* Realloc the size of parameters and data we will return */
1124         *pparams = (char *)SMB_REALLOC(*pparams, 30);
1125         if(*pparams == NULL ) {
1126                 reply_nterror(req, NT_STATUS_NO_MEMORY);
1127                 goto out;
1128         }
1129         params = *pparams;
1130
1131         SSVAL(params,0,fsp->fnum);
1132         SSVAL(params,2,fattr);
1133         srv_put_dos_date2(params,4, mtime);
1134         SIVAL(params,8, (uint32)size);
1135         SSVAL(params,12,deny_mode);
1136         SSVAL(params,14,0); /* open_type - file or directory. */
1137         SSVAL(params,16,0); /* open_state - only valid for IPC device. */
1138
1139         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1140                 smb_action |= EXTENDED_OPLOCK_GRANTED;
1141         }
1142
1143         SSVAL(params,18,smb_action);
1144
1145         /*
1146          * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1147          */
1148         SIVAL(params,20,inode);
1149         SSVAL(params,24,0); /* Padding. */
1150         if (flags & 8) {
1151                 uint32 ea_size = estimate_ea_size(conn, fsp, fsp->fsp_name);
1152                 SIVAL(params, 26, ea_size);
1153         } else {
1154                 SIVAL(params, 26, 0);
1155         }
1156
1157         /* Send the required number of replies */
1158         send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes);
1159  out:
1160         TALLOC_FREE(smb_fname);
1161 }
1162
1163 /*********************************************************
1164  Routine to check if a given string matches exactly.
1165  as a special case a mask of "." does NOT match. That
1166  is required for correct wildcard semantics
1167  Case can be significant or not.
1168 **********************************************************/
1169
1170 static bool exact_match(connection_struct *conn,
1171                 const char *str,
1172                 const char *mask)
1173 {
1174         if (mask[0] == '.' && mask[1] == 0)
1175                 return False;
1176         if (dptr_has_wild(conn->dirptr)) {
1177                 return False;
1178         }
1179         if (conn->case_sensitive)
1180                 return strcmp(str,mask)==0;
1181         else
1182                 return StrCaseCmp(str,mask) == 0;
1183 }
1184
1185 /****************************************************************************
1186  Return the filetype for UNIX extensions.
1187 ****************************************************************************/
1188
1189 static uint32 unix_filetype(mode_t mode)
1190 {
1191         if(S_ISREG(mode))
1192                 return UNIX_TYPE_FILE;
1193         else if(S_ISDIR(mode))
1194                 return UNIX_TYPE_DIR;
1195 #ifdef S_ISLNK
1196         else if(S_ISLNK(mode))
1197                 return UNIX_TYPE_SYMLINK;
1198 #endif
1199 #ifdef S_ISCHR
1200         else if(S_ISCHR(mode))
1201                 return UNIX_TYPE_CHARDEV;
1202 #endif
1203 #ifdef S_ISBLK
1204         else if(S_ISBLK(mode))
1205                 return UNIX_TYPE_BLKDEV;
1206 #endif
1207 #ifdef S_ISFIFO
1208         else if(S_ISFIFO(mode))
1209                 return UNIX_TYPE_FIFO;
1210 #endif
1211 #ifdef S_ISSOCK
1212         else if(S_ISSOCK(mode))
1213                 return UNIX_TYPE_SOCKET;
1214 #endif
1215
1216         DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
1217         return UNIX_TYPE_UNKNOWN;
1218 }
1219
1220 /****************************************************************************
1221  Map wire perms onto standard UNIX permissions. Obey share restrictions.
1222 ****************************************************************************/
1223
1224 enum perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR};
1225
1226 static NTSTATUS unix_perms_from_wire( connection_struct *conn,
1227                                 const SMB_STRUCT_STAT *psbuf,
1228                                 uint32 perms,
1229                                 enum perm_type ptype,
1230                                 mode_t *ret_perms)
1231 {
1232         mode_t ret = 0;
1233
1234         if (perms == SMB_MODE_NO_CHANGE) {
1235                 if (!VALID_STAT(*psbuf)) {
1236                         return NT_STATUS_INVALID_PARAMETER;
1237                 } else {
1238                         *ret_perms = psbuf->st_ex_mode;
1239                         return NT_STATUS_OK;
1240                 }
1241         }
1242
1243         ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
1244         ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
1245         ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
1246         ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
1247         ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
1248         ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
1249         ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
1250         ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
1251         ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
1252 #ifdef S_ISVTX
1253         ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
1254 #endif
1255 #ifdef S_ISGID
1256         ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
1257 #endif
1258 #ifdef S_ISUID
1259         ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
1260 #endif
1261
1262         switch (ptype) {
1263         case PERM_NEW_FILE:
1264                 /* Apply mode mask */
1265                 ret &= lp_create_mask(SNUM(conn));
1266                 /* Add in force bits */
1267                 ret |= lp_force_create_mode(SNUM(conn));
1268                 break;
1269         case PERM_NEW_DIR:
1270                 ret &= lp_dir_mask(SNUM(conn));
1271                 /* Add in force bits */
1272                 ret |= lp_force_dir_mode(SNUM(conn));
1273                 break;
1274         case PERM_EXISTING_FILE:
1275                 /* Apply mode mask */
1276                 ret &= lp_security_mask(SNUM(conn));
1277                 /* Add in force bits */
1278                 ret |= lp_force_security_mode(SNUM(conn));
1279                 break;
1280         case PERM_EXISTING_DIR:
1281                 /* Apply mode mask */
1282                 ret &= lp_dir_security_mask(SNUM(conn));
1283                 /* Add in force bits */
1284                 ret |= lp_force_dir_security_mode(SNUM(conn));
1285                 break;
1286         }
1287
1288         *ret_perms = ret;
1289         return NT_STATUS_OK;
1290 }
1291
1292 /****************************************************************************
1293  Needed to show the msdfs symlinks as directories. Modifies psbuf
1294  to be a directory if it's a msdfs link.
1295 ****************************************************************************/
1296
1297 static bool check_msdfs_link(connection_struct *conn,
1298                                 const char *pathname,
1299                                 SMB_STRUCT_STAT *psbuf)
1300 {
1301         int saved_errno = errno;
1302         if(lp_host_msdfs() &&
1303                 lp_msdfs_root(SNUM(conn)) &&
1304                 is_msdfs_link(conn, pathname, psbuf)) {
1305
1306                 DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1307                         "as a directory\n",
1308                         pathname));
1309                 psbuf->st_ex_mode = (psbuf->st_ex_mode & 0xFFF) | S_IFDIR;
1310                 errno = saved_errno;
1311                 return true;
1312         }
1313         errno = saved_errno;
1314         return false;
1315 }
1316
1317
1318 /****************************************************************************
1319  Get a level dependent lanman2 dir entry.
1320 ****************************************************************************/
1321
1322 static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
1323                                 connection_struct *conn,
1324                                 uint16 flags2,
1325                                 const char *path_mask,
1326                                 uint32 dirtype,
1327                                 int info_level,
1328                                 int requires_resume_key,
1329                                 bool dont_descend,
1330                                 bool ask_sharemode,
1331                                 char **ppdata,
1332                                 char *base_data,
1333                                 char *end_data,
1334                                 int space_remaining,
1335                                 bool *out_of_space,
1336                                 bool *got_exact_match,
1337                                 int *last_entry_off,
1338                                 struct ea_list *name_list)
1339 {
1340         char *dname;
1341         bool found = False;
1342         SMB_STRUCT_STAT sbuf;
1343         const char *mask = NULL;
1344         char *pathreal = NULL;
1345         char *fname = NULL;
1346         char *p, *q, *pdata = *ppdata;
1347         uint32 reskey=0;
1348         long prev_dirpos=0;
1349         uint32 mode=0;
1350         SMB_OFF_T file_size = 0;
1351         uint64_t allocation_size = 0;
1352         uint32 len;
1353         struct timespec mdate_ts, adate_ts, create_date_ts;
1354         time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1355         char *nameptr;
1356         char *last_entry_ptr;
1357         bool was_8_3;
1358         uint32 nt_extmode; /* Used for NT connections instead of mode */
1359         bool needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
1360         bool check_mangled_names = lp_manglednames(conn->params);
1361         char mangled_name[13]; /* mangled 8.3 name. */
1362
1363         *out_of_space = False;
1364         *got_exact_match = False;
1365
1366         ZERO_STRUCT(mdate_ts);
1367         ZERO_STRUCT(adate_ts);
1368         ZERO_STRUCT(create_date_ts);
1369
1370         if (!conn->dirptr) {
1371                 return(False);
1372         }
1373
1374         p = strrchr_m(path_mask,'/');
1375         if(p != NULL) {
1376                 if(p[1] == '\0') {
1377                         mask = talloc_strdup(ctx,"*.*");
1378                 } else {
1379                         mask = p+1;
1380                 }
1381         } else {
1382                 mask = path_mask;
1383         }
1384
1385         while (!found) {
1386                 bool got_match;
1387                 bool ms_dfs_link = False;
1388
1389                 /* Needed if we run out of space */
1390                 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
1391                 dname = dptr_ReadDirName(ctx,conn->dirptr,&curr_dirpos,&sbuf);
1392
1393                 /*
1394                  * Due to bugs in NT client redirectors we are not using
1395                  * resume keys any more - set them to zero.
1396                  * Check out the related comments in findfirst/findnext.
1397                  * JRA.
1398                  */
1399
1400                 reskey = 0;
1401
1402                 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
1403                         (long)conn->dirptr,curr_dirpos));
1404
1405                 if (!dname) {
1406                         return(False);
1407                 }
1408
1409                 /*
1410                  * fname may get mangled, dname is never mangled.
1411                  * Whenever we're accessing the filesystem we use
1412                  * pathreal which is composed from dname.
1413                  */
1414
1415                 pathreal = NULL;
1416                 fname = dname;
1417
1418                 /* Mangle fname if it's an illegal name. */
1419                 if (mangle_must_mangle(dname,conn->params)) {
1420                         if (!name_to_8_3(dname,mangled_name,True,conn->params)) {
1421                                 TALLOC_FREE(fname);
1422                                 continue; /* Error - couldn't mangle. */
1423                         }
1424                         fname = talloc_strdup(ctx, mangled_name);
1425                         if (!fname) {
1426                                 return False;
1427                         }
1428                 }
1429
1430                 if(!(got_match = *got_exact_match = exact_match(conn, fname, mask))) {
1431                         got_match = mask_match(fname, mask, conn->case_sensitive);
1432                 }
1433
1434                 if(!got_match && check_mangled_names &&
1435                    !mangle_is_8_3(fname, False, conn->params)) {
1436                         /*
1437                          * It turns out that NT matches wildcards against
1438                          * both long *and* short names. This may explain some
1439                          * of the wildcard wierdness from old DOS clients
1440                          * that some people have been seeing.... JRA.
1441                          */
1442                         /* Force the mangling into 8.3. */
1443                         if (!name_to_8_3( fname, mangled_name, False, conn->params)) {
1444                                 TALLOC_FREE(fname);
1445                                 continue; /* Error - couldn't mangle. */
1446                         }
1447
1448                         if(!(got_match = *got_exact_match = exact_match(conn, mangled_name, mask))) {
1449                                 got_match = mask_match(mangled_name, mask, conn->case_sensitive);
1450                         }
1451                 }
1452
1453                 if (got_match) {
1454                         bool isdots = (ISDOT(dname) || ISDOTDOT(dname));
1455                         struct smb_filename *smb_fname = NULL;
1456                         NTSTATUS status;
1457
1458                         if (dont_descend && !isdots) {
1459                                 TALLOC_FREE(fname);
1460                                 continue;
1461                         }
1462
1463                         if (needslash) {
1464                                 pathreal = NULL;
1465                                 pathreal = talloc_asprintf(ctx,
1466                                         "%s/%s",
1467                                         conn->dirpath,
1468                                         dname);
1469                         } else {
1470                                 pathreal = talloc_asprintf(ctx,
1471                                         "%s%s",
1472                                         conn->dirpath,
1473                                         dname);
1474                         }
1475
1476                         if (!pathreal) {
1477                                 TALLOC_FREE(fname);
1478                                 return False;
1479                         }
1480
1481                         /* A dirent from dptr_ReadDirName isn't a stream. */
1482                         status = create_synthetic_smb_fname(ctx, pathreal,
1483                                                             NULL, &sbuf,
1484                                                             &smb_fname);
1485                         if (!NT_STATUS_IS_OK(status)) {
1486                                 TALLOC_FREE(fname);
1487                                 return false;
1488                         }
1489
1490                         if (INFO_LEVEL_IS_UNIX(info_level)) {
1491                                 if (SMB_VFS_LSTAT(conn, smb_fname) != 0) {
1492                                         DEBUG(5,("get_lanman2_dir_entry: "
1493                                                  "Couldn't lstat [%s] (%s)\n",
1494                                                  smb_fname_str_dbg(smb_fname),
1495                                                  strerror(errno)));
1496                                         TALLOC_FREE(smb_fname);
1497                                         TALLOC_FREE(pathreal);
1498                                         TALLOC_FREE(fname);
1499                                         continue;
1500                                 }
1501                         } else if (!VALID_STAT(smb_fname->st) &&
1502                                    SMB_VFS_STAT(conn, smb_fname) != 0) {
1503                                 /* Needed to show the msdfs symlinks as
1504                                  * directories */
1505
1506                                 ms_dfs_link =
1507                                     check_msdfs_link(conn,
1508                                                      smb_fname->base_name,
1509                                                      &smb_fname->st);
1510                                 if (!ms_dfs_link) {
1511                                         DEBUG(5,("get_lanman2_dir_entry: "
1512                                                  "Couldn't stat [%s] (%s)\n",
1513                                                  smb_fname_str_dbg(smb_fname),
1514                                                  strerror(errno)));
1515                                         TALLOC_FREE(smb_fname);
1516                                         TALLOC_FREE(pathreal);
1517                                         TALLOC_FREE(fname);
1518                                         continue;
1519                                 }
1520                         }
1521
1522                         if (ms_dfs_link) {
1523                                 mode = dos_mode_msdfs(conn, smb_fname);
1524                         } else {
1525                                 mode = dos_mode(conn, smb_fname);
1526                         }
1527
1528                         if (!dir_check_ftype(conn,mode,dirtype)) {
1529                                 DEBUG(5,("get_lanman2_dir_entry: [%s] attribs didn't match %x\n",fname,dirtype));
1530                                 TALLOC_FREE(smb_fname);
1531                                 TALLOC_FREE(pathreal);
1532                                 TALLOC_FREE(fname);
1533                                 continue;
1534                         }
1535
1536                         if (!(mode & aDIR)) {
1537                                 file_size = get_file_size_stat(&smb_fname->st);
1538                         }
1539                         allocation_size =
1540                             SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
1541
1542                         if (ask_sharemode) {
1543                                 struct timespec write_time_ts;
1544                                 struct file_id fileid;
1545
1546                                 ZERO_STRUCT(write_time_ts);
1547                                 fileid = vfs_file_id_from_sbuf(conn,
1548                                                                &smb_fname->st);
1549                                 get_file_infos(fileid, NULL, &write_time_ts);
1550                                 if (!null_timespec(write_time_ts)) {
1551                                         update_stat_ex_mtime(&smb_fname->st,
1552                                                              write_time_ts);
1553                                 }
1554                         }
1555
1556                         mdate_ts = smb_fname->st.st_ex_mtime;
1557                         adate_ts = smb_fname->st.st_ex_atime;
1558                         create_date_ts = smb_fname->st.st_ex_btime;
1559
1560                         if (lp_dos_filetime_resolution(SNUM(conn))) {
1561                                 dos_filetime_timespec(&create_date_ts);
1562                                 dos_filetime_timespec(&mdate_ts);
1563                                 dos_filetime_timespec(&adate_ts);
1564                         }
1565
1566                         create_date = convert_timespec_to_time_t(create_date_ts);
1567                         mdate = convert_timespec_to_time_t(mdate_ts);
1568                         adate = convert_timespec_to_time_t(adate_ts);
1569
1570                         DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n",
1571                                  smb_fname_str_dbg(smb_fname), fname));
1572
1573                         found = True;
1574
1575                         dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
1576                         sbuf = smb_fname->st;
1577
1578                         TALLOC_FREE(smb_fname);
1579                 }
1580
1581                 if (!found)
1582                         TALLOC_FREE(fname);
1583         }
1584
1585         p = pdata;
1586         last_entry_ptr = p;
1587
1588         nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
1589
1590         switch (info_level) {
1591                 case SMB_FIND_INFO_STANDARD:
1592                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1593                         if(requires_resume_key) {
1594                                 SIVAL(p,0,reskey);
1595                                 p += 4;
1596                         }
1597                         srv_put_dos_date2(p,0,create_date);
1598                         srv_put_dos_date2(p,4,adate);
1599                         srv_put_dos_date2(p,8,mdate);
1600                         SIVAL(p,12,(uint32)file_size);
1601                         SIVAL(p,16,(uint32)allocation_size);
1602                         SSVAL(p,20,mode);
1603                         p += 23;
1604                         nameptr = p;
1605                         if (flags2 & FLAGS2_UNICODE_STRINGS) {
1606                                 p += ucs2_align(base_data, p, 0);
1607                         }
1608                         len = srvstr_push(base_data, flags2, p,
1609                                           fname, PTR_DIFF(end_data, p),
1610                                           STR_TERMINATE);
1611                         if (flags2 & FLAGS2_UNICODE_STRINGS) {
1612                                 if (len > 2) {
1613                                         SCVAL(nameptr, -1, len - 2);
1614                                 } else {
1615                                         SCVAL(nameptr, -1, 0);
1616                                 }
1617                         } else {
1618                                 if (len > 1) {
1619                                         SCVAL(nameptr, -1, len - 1);
1620                                 } else {
1621                                         SCVAL(nameptr, -1, 0);
1622                                 }
1623                         }
1624                         p += len;
1625                         break;
1626
1627                 case SMB_FIND_EA_SIZE:
1628                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
1629                         if(requires_resume_key) {
1630                                 SIVAL(p,0,reskey);
1631                                 p += 4;
1632                         }
1633                         srv_put_dos_date2(p,0,create_date);
1634                         srv_put_dos_date2(p,4,adate);
1635                         srv_put_dos_date2(p,8,mdate);
1636                         SIVAL(p,12,(uint32)file_size);
1637                         SIVAL(p,16,(uint32)allocation_size);
1638                         SSVAL(p,20,mode);
1639                         {
1640                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1641                                 SIVAL(p,22,ea_size); /* Extended attributes */
1642                         }
1643                         p += 27;
1644                         nameptr = p - 1;
1645                         len = srvstr_push(base_data, flags2,
1646                                           p, fname, PTR_DIFF(end_data, p),
1647                                           STR_TERMINATE | STR_NOALIGN);
1648                         if (flags2 & FLAGS2_UNICODE_STRINGS) {
1649                                 if (len > 2) {
1650                                         len -= 2;
1651                                 } else {
1652                                         len = 0;
1653                                 }
1654                         } else {
1655                                 if (len > 1) {
1656                                         len -= 1;
1657                                 } else {
1658                                         len = 0;
1659                                 }
1660                         }
1661                         SCVAL(nameptr,0,len);
1662                         p += len;
1663                         SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1664                         break;
1665
1666                 case SMB_FIND_EA_LIST:
1667                 {
1668                         struct ea_list *file_list = NULL;
1669                         size_t ea_len = 0;
1670
1671                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1672                         if (!name_list) {
1673                                 return False;
1674                         }
1675                         if(requires_resume_key) {
1676                                 SIVAL(p,0,reskey);
1677                                 p += 4;
1678                         }
1679                         srv_put_dos_date2(p,0,create_date);
1680                         srv_put_dos_date2(p,4,adate);
1681                         srv_put_dos_date2(p,8,mdate);
1682                         SIVAL(p,12,(uint32)file_size);
1683                         SIVAL(p,16,(uint32)allocation_size);
1684                         SSVAL(p,20,mode);
1685                         p += 22; /* p now points to the EA area. */
1686
1687                         file_list = get_ea_list_from_file(ctx, conn, NULL, pathreal, &ea_len);
1688                         name_list = ea_list_union(name_list, file_list, &ea_len);
1689
1690                         /* We need to determine if this entry will fit in the space available. */
1691                         /* Max string size is 255 bytes. */
1692                         if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1693                                 /* Move the dirptr back to prev_dirpos */
1694                                 dptr_SeekDir(conn->dirptr, prev_dirpos);
1695                                 *out_of_space = True;
1696                                 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1697                                 return False; /* Not finished - just out of space */
1698                         }
1699
1700                         /* Push the ea_data followed by the name. */
1701                         p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
1702                         nameptr = p;
1703                         len = srvstr_push(base_data, flags2,
1704                                           p + 1, fname, PTR_DIFF(end_data, p+1),
1705                                           STR_TERMINATE | STR_NOALIGN);
1706                         if (flags2 & FLAGS2_UNICODE_STRINGS) {
1707                                 if (len > 2) {
1708                                         len -= 2;
1709                                 } else {
1710                                         len = 0;
1711                                 }
1712                         } else {
1713                                 if (len > 1) {
1714                                         len -= 1;
1715                                 } else {
1716                                         len = 0;
1717                                 }
1718                         }
1719                         SCVAL(nameptr,0,len);
1720                         p += len + 1;
1721                         SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1722                         break;
1723                 }
1724
1725                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1726                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1727                         was_8_3 = mangle_is_8_3(fname, True, conn->params);
1728                         p += 4;
1729                         SIVAL(p,0,reskey); p += 4;
1730                         put_long_date_timespec(p,create_date_ts); p += 8;
1731                         put_long_date_timespec(p,adate_ts); p += 8;
1732                         put_long_date_timespec(p,mdate_ts); p += 8;
1733                         put_long_date_timespec(p,mdate_ts); p += 8;
1734                         SOFF_T(p,0,file_size); p += 8;
1735                         SOFF_T(p,0,allocation_size); p += 8;
1736                         SIVAL(p,0,nt_extmode); p += 4;
1737                         q = p; p += 4; /* q is placeholder for name length. */
1738                         {
1739                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1740                                 SIVAL(p,0,ea_size); /* Extended attributes */
1741                                 p += 4;
1742                         }
1743                         /* Clear the short name buffer. This is
1744                          * IMPORTANT as not doing so will trigger
1745                          * a Win2k client bug. JRA.
1746                          */
1747                         if (!was_8_3 && check_mangled_names) {
1748                                 if (!name_to_8_3(fname,mangled_name,True,
1749                                                    conn->params)) {
1750                                         /* Error - mangle failed ! */
1751                                         memset(mangled_name,'\0',12);
1752                                 }
1753                                 mangled_name[12] = 0;
1754                                 len = srvstr_push(base_data, flags2,
1755                                                   p+2, mangled_name, 24,
1756                                                   STR_UPPER|STR_UNICODE);
1757                                 if (len < 24) {
1758                                         memset(p + 2 + len,'\0',24 - len);
1759                                 }
1760                                 SSVAL(p, 0, len);
1761                         } else {
1762                                 memset(p,'\0',26);
1763                         }
1764                         p += 2 + 24;
1765                         len = srvstr_push(base_data, flags2, p,
1766                                           fname, PTR_DIFF(end_data, p),
1767                                           STR_TERMINATE_ASCII);
1768                         SIVAL(q,0,len);
1769                         p += len;
1770                         SIVAL(p,0,0); /* Ensure any padding is null. */
1771                         len = PTR_DIFF(p, pdata);
1772                         len = (len + 3) & ~3;
1773                         SIVAL(pdata,0,len);
1774                         p = pdata + len;
1775                         break;
1776
1777                 case SMB_FIND_FILE_DIRECTORY_INFO:
1778                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1779                         p += 4;
1780                         SIVAL(p,0,reskey); p += 4;
1781                         put_long_date_timespec(p,create_date_ts); p += 8;
1782                         put_long_date_timespec(p,adate_ts); p += 8;
1783                         put_long_date_timespec(p,mdate_ts); p += 8;
1784                         put_long_date_timespec(p,mdate_ts); p += 8;
1785                         SOFF_T(p,0,file_size); p += 8;
1786                         SOFF_T(p,0,allocation_size); p += 8;
1787                         SIVAL(p,0,nt_extmode); p += 4;
1788                         len = srvstr_push(base_data, flags2,
1789                                           p + 4, fname, PTR_DIFF(end_data, p+4),
1790                                           STR_TERMINATE_ASCII);
1791                         SIVAL(p,0,len);
1792                         p += 4 + len;
1793                         SIVAL(p,0,0); /* Ensure any padding is null. */
1794                         len = PTR_DIFF(p, pdata);
1795                         len = (len + 3) & ~3;
1796                         SIVAL(pdata,0,len);
1797                         p = pdata + len;
1798                         break;
1799
1800                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1801                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1802                         p += 4;
1803                         SIVAL(p,0,reskey); p += 4;
1804                         put_long_date_timespec(p,create_date_ts); p += 8;
1805                         put_long_date_timespec(p,adate_ts); p += 8;
1806                         put_long_date_timespec(p,mdate_ts); p += 8;
1807                         put_long_date_timespec(p,mdate_ts); p += 8;
1808                         SOFF_T(p,0,file_size); p += 8;
1809                         SOFF_T(p,0,allocation_size); p += 8;
1810                         SIVAL(p,0,nt_extmode); p += 4;
1811                         q = p; p += 4; /* q is placeholder for name length. */
1812                         {
1813                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1814                                 SIVAL(p,0,ea_size); /* Extended attributes */
1815                                 p +=4;
1816                         }
1817                         len = srvstr_push(base_data, flags2, p,
1818                                           fname, PTR_DIFF(end_data, p),
1819                                           STR_TERMINATE_ASCII);
1820                         SIVAL(q, 0, len);
1821                         p += len;
1822
1823                         SIVAL(p,0,0); /* Ensure any padding is null. */
1824                         len = PTR_DIFF(p, pdata);
1825                         len = (len + 3) & ~3;
1826                         SIVAL(pdata,0,len);
1827                         p = pdata + len;
1828                         break;
1829
1830                 case SMB_FIND_FILE_NAMES_INFO:
1831                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1832                         p += 4;
1833                         SIVAL(p,0,reskey); p += 4;
1834                         p += 4;
1835                         /* this must *not* be null terminated or w2k gets in a loop trying to set an
1836                            acl on a dir (tridge) */
1837                         len = srvstr_push(base_data, flags2, p,
1838                                           fname, PTR_DIFF(end_data, p),
1839                                           STR_TERMINATE_ASCII);
1840                         SIVAL(p, -4, len);
1841                         p += len;
1842                         SIVAL(p,0,0); /* Ensure any padding is null. */
1843                         len = PTR_DIFF(p, pdata);
1844                         len = (len + 3) & ~3;
1845                         SIVAL(pdata,0,len);
1846                         p = pdata + len;
1847                         break;
1848
1849                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1850                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1851                         p += 4;
1852                         SIVAL(p,0,reskey); p += 4;
1853                         put_long_date_timespec(p,create_date_ts); p += 8;
1854                         put_long_date_timespec(p,adate_ts); p += 8;
1855                         put_long_date_timespec(p,mdate_ts); p += 8;
1856                         put_long_date_timespec(p,mdate_ts); p += 8;
1857                         SOFF_T(p,0,file_size); p += 8;
1858                         SOFF_T(p,0,allocation_size); p += 8;
1859                         SIVAL(p,0,nt_extmode); p += 4;
1860                         q = p; p += 4; /* q is placeholder for name length. */
1861                         {
1862                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1863                                 SIVAL(p,0,ea_size); /* Extended attributes */
1864                                 p +=4;
1865                         }
1866                         SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1867                         SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
1868                         SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
1869                         len = srvstr_push(base_data, flags2, p,
1870                                           fname, PTR_DIFF(end_data, p),
1871                                           STR_TERMINATE_ASCII);
1872                         SIVAL(q, 0, len);
1873                         p += len; 
1874                         SIVAL(p,0,0); /* Ensure any padding is null. */
1875                         len = PTR_DIFF(p, pdata);
1876                         len = (len + 3) & ~3;
1877                         SIVAL(pdata,0,len);
1878                         p = pdata + len;
1879                         break;
1880
1881                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1882                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1883                         was_8_3 = mangle_is_8_3(fname, True, conn->params);
1884                         p += 4;
1885                         SIVAL(p,0,reskey); p += 4;
1886                         put_long_date_timespec(p,create_date_ts); p += 8;
1887                         put_long_date_timespec(p,adate_ts); p += 8;
1888                         put_long_date_timespec(p,mdate_ts); p += 8;
1889                         put_long_date_timespec(p,mdate_ts); p += 8;
1890                         SOFF_T(p,0,file_size); p += 8;
1891                         SOFF_T(p,0,allocation_size); p += 8;
1892                         SIVAL(p,0,nt_extmode); p += 4;
1893                         q = p; p += 4; /* q is placeholder for name length */
1894                         {
1895                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1896                                 SIVAL(p,0,ea_size); /* Extended attributes */
1897                                 p +=4;
1898                         }
1899                         /* Clear the short name buffer. This is
1900                          * IMPORTANT as not doing so will trigger
1901                          * a Win2k client bug. JRA.
1902                          */
1903                         if (!was_8_3 && check_mangled_names) {
1904                                 if (!name_to_8_3(fname,mangled_name,True,
1905                                                 conn->params)) {
1906                                         /* Error - mangle failed ! */
1907                                         memset(mangled_name,'\0',12);
1908                                 }
1909                                 mangled_name[12] = 0;
1910                                 len = srvstr_push(base_data, flags2,
1911                                                   p+2, mangled_name, 24,
1912                                                   STR_UPPER|STR_UNICODE);
1913                                 SSVAL(p, 0, len);
1914                                 if (len < 24) {
1915                                         memset(p + 2 + len,'\0',24 - len);
1916                                 }
1917                                 SSVAL(p, 0, len);
1918                         } else {
1919                                 memset(p,'\0',26);
1920                         }
1921                         p += 26;
1922                         SSVAL(p,0,0); p += 2; /* Reserved ? */
1923                         SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
1924                         SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
1925                         len = srvstr_push(base_data, flags2, p,
1926                                           fname, PTR_DIFF(end_data, p),
1927                                           STR_TERMINATE_ASCII);
1928                         SIVAL(q,0,len);
1929                         p += len;
1930                         SIVAL(p,0,0); /* Ensure any padding is null. */
1931                         len = PTR_DIFF(p, pdata);
1932                         len = (len + 3) & ~3;
1933                         SIVAL(pdata,0,len);
1934                         p = pdata + len;
1935                         break;
1936
1937                 /* CIFS UNIX Extension. */
1938
1939                 case SMB_FIND_FILE_UNIX:
1940                 case SMB_FIND_FILE_UNIX_INFO2:
1941                         p+= 4;
1942                         SIVAL(p,0,reskey); p+= 4;    /* Used for continuing search. */
1943
1944                         /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1945
1946                         if (info_level == SMB_FIND_FILE_UNIX) {
1947                                 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1948                                 p = store_file_unix_basic(conn, p,
1949                                                         NULL, &sbuf);
1950                                 len = srvstr_push(base_data, flags2, p,
1951                                                   fname, PTR_DIFF(end_data, p),
1952                                                   STR_TERMINATE);
1953                         } else {
1954                                 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
1955                                 p = store_file_unix_basic_info2(conn, p,
1956                                                         NULL, &sbuf);
1957                                 nameptr = p;
1958                                 p += 4;
1959                                 len = srvstr_push(base_data, flags2, p, fname,
1960                                                   PTR_DIFF(end_data, p), 0);
1961                                 SIVAL(nameptr, 0, len);
1962                         }
1963
1964                         p += len;
1965                         SIVAL(p,0,0); /* Ensure any padding is null. */
1966
1967                         len = PTR_DIFF(p, pdata);
1968                         len = (len + 3) & ~3;
1969                         SIVAL(pdata,0,len);     /* Offset from this structure to the beginning of the next one */
1970                         p = pdata + len;
1971                         /* End of SMB_QUERY_FILE_UNIX_BASIC */
1972
1973                         break;
1974
1975                 default:
1976                         TALLOC_FREE(fname);
1977                         return(False);
1978         }
1979
1980         TALLOC_FREE(fname);
1981         if (PTR_DIFF(p,pdata) > space_remaining) {
1982                 /* Move the dirptr back to prev_dirpos */
1983                 dptr_SeekDir(conn->dirptr, prev_dirpos);
1984                 *out_of_space = True;
1985                 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1986                 return False; /* Not finished - just out of space */
1987         }
1988
1989         /* Setup the last entry pointer, as an offset from base_data */
1990         *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1991         /* Advance the data pointer to the next slot */
1992         *ppdata = p;
1993
1994         return(found);
1995 }
1996
1997 /****************************************************************************
1998  Reply to a TRANS2_FINDFIRST.
1999 ****************************************************************************/
2000
2001 static void call_trans2findfirst(connection_struct *conn,
2002                                  struct smb_request *req,
2003                                  char **pparams, int total_params,
2004                                  char **ppdata, int total_data,
2005                                  unsigned int max_data_bytes)
2006 {
2007         /* We must be careful here that we don't return more than the
2008                 allowed number of data bytes. If this means returning fewer than
2009                 maxentries then so be it. We assume that the redirector has
2010                 enough room for the fixed number of parameter bytes it has
2011                 requested. */
2012         struct smb_filename *smb_dname = NULL;
2013         char *params = *pparams;
2014         char *pdata = *ppdata;
2015         char *data_end;
2016         uint32 dirtype;
2017         int maxentries;
2018         uint16 findfirst_flags;
2019         bool close_after_first;
2020         bool close_if_end;
2021         bool requires_resume_key;
2022         int info_level;
2023         char *directory = NULL;
2024         char *mask = NULL;
2025         char *p;
2026         int last_entry_off=0;
2027         int dptr_num = -1;
2028         int numentries = 0;
2029         int i;
2030         bool finished = False;
2031         bool dont_descend = False;
2032         bool out_of_space = False;
2033         int space_remaining;
2034         bool mask_contains_wcard = False;
2035         struct ea_list *ea_list = NULL;
2036         NTSTATUS ntstatus = NT_STATUS_OK;
2037         bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2038         TALLOC_CTX *ctx = talloc_tos();
2039
2040         if (total_params < 13) {
2041                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2042                 return;
2043         }
2044
2045         dirtype = SVAL(params,0);
2046         maxentries = SVAL(params,2);
2047         findfirst_flags = SVAL(params,4);
2048         close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
2049         close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2050         requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2051         info_level = SVAL(params,6);
2052
2053         DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2054 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
2055                 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
2056                 info_level, max_data_bytes));
2057
2058         if (!maxentries) {
2059                 /* W2K3 seems to treat zero as 1. */
2060                 maxentries = 1;
2061         }
2062
2063         switch (info_level) {
2064                 case SMB_FIND_INFO_STANDARD:
2065                 case SMB_FIND_EA_SIZE:
2066                 case SMB_FIND_EA_LIST:
2067                 case SMB_FIND_FILE_DIRECTORY_INFO:
2068                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2069                 case SMB_FIND_FILE_NAMES_INFO:
2070                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2071                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2072                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2073                         break;
2074                 case SMB_FIND_FILE_UNIX:
2075                 case SMB_FIND_FILE_UNIX_INFO2:
2076                         /* Always use filesystem for UNIX mtime query. */
2077                         ask_sharemode = false;
2078                         if (!lp_unix_extensions()) {
2079                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2080                                 return;
2081                         }
2082                         break;
2083                 default:
2084                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2085                         return;
2086         }
2087
2088         srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
2089                               params+12, total_params - 12,
2090                               STR_TERMINATE, &ntstatus, &mask_contains_wcard);
2091         if (!NT_STATUS_IS_OK(ntstatus)) {
2092                 reply_nterror(req, ntstatus);
2093                 return;
2094         }
2095
2096         ntstatus = resolve_dfspath_wcard(ctx, conn,
2097                         req->flags2 & FLAGS2_DFS_PATHNAMES,
2098                         directory,
2099                         &directory,
2100                         &mask_contains_wcard);
2101         if (!NT_STATUS_IS_OK(ntstatus)) {
2102                 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
2103                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2104                                         ERRSRV, ERRbadpath);
2105                         return;
2106                 }
2107                 reply_nterror(req, ntstatus);
2108                 return;
2109         }
2110
2111         ntstatus = unix_convert(ctx, conn, directory, &smb_dname,
2112                                 (UCF_SAVE_LCOMP | UCF_ALLOW_WCARD_LCOMP));
2113         if (!NT_STATUS_IS_OK(ntstatus)) {
2114                 reply_nterror(req, ntstatus);
2115                 return;
2116         }
2117
2118         mask = smb_dname->original_lcomp;
2119
2120         ntstatus = get_full_smb_filename(ctx, smb_dname, &directory);
2121         TALLOC_FREE(smb_dname);
2122         if (!NT_STATUS_IS_OK(ntstatus)) {
2123                 reply_nterror(req, ntstatus);
2124                 return;
2125         }
2126
2127         ntstatus = check_name(conn, directory);
2128         if (!NT_STATUS_IS_OK(ntstatus)) {
2129                 reply_nterror(req, ntstatus);
2130                 return;
2131         }
2132
2133         p = strrchr_m(directory,'/');
2134         if(p == NULL) {
2135                 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2136                 if((directory[0] == '.') && (directory[1] == '\0')) {
2137                         mask = talloc_strdup(ctx,"*");
2138                         if (!mask) {
2139                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2140                                 return;
2141                         }
2142                         mask_contains_wcard = True;
2143                 }
2144                 directory = talloc_strdup(talloc_tos(), "./");
2145                 if (!directory) {
2146                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2147                         return;
2148                 }
2149         } else {
2150                 *p = 0;
2151         }
2152
2153         DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
2154
2155         if (info_level == SMB_FIND_EA_LIST) {
2156                 uint32 ea_size;
2157
2158                 if (total_data < 4) {
2159                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2160                         return;
2161                 }
2162
2163                 ea_size = IVAL(pdata,0);
2164                 if (ea_size != total_data) {
2165                         DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2166 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2167                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2168                         return;
2169                 }
2170
2171                 if (!lp_ea_support(SNUM(conn))) {
2172                         reply_doserror(req, ERRDOS, ERReasnotsupported);
2173                         return;
2174                 }
2175
2176                 /* Pull out the list of names. */
2177                 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2178                 if (!ea_list) {
2179                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2180                         return;
2181                 }
2182         }
2183
2184         *ppdata = (char *)SMB_REALLOC(
2185                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2186         if(*ppdata == NULL ) {
2187                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2188                 return;
2189         }
2190         pdata = *ppdata;
2191         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2192
2193         /* Realloc the params space */
2194         *pparams = (char *)SMB_REALLOC(*pparams, 10);
2195         if (*pparams == NULL) {
2196                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2197                 return;
2198         }
2199         params = *pparams;
2200
2201         /* Save the wildcard match and attribs we are using on this directory -
2202                 needed as lanman2 assumes these are being saved between calls */
2203
2204         ntstatus = dptr_create(conn,
2205                                 directory,
2206                                 False,
2207                                 True,
2208                                 req->smbpid,
2209                                 mask,
2210                                 mask_contains_wcard,
2211                                 dirtype,
2212                                 &conn->dirptr);
2213
2214         if (!NT_STATUS_IS_OK(ntstatus)) {
2215                 reply_nterror(req, ntstatus);
2216                 return;
2217         }
2218
2219         dptr_num = dptr_dnum(conn->dirptr);
2220         DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
2221
2222         /* Initialize per TRANS2_FIND_FIRST operation data */
2223         dptr_init_search_op(conn->dirptr);
2224
2225         /* We don't need to check for VOL here as this is returned by
2226                 a different TRANS2 call. */
2227
2228         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
2229         if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2230                 dont_descend = True;
2231
2232         p = pdata;
2233         space_remaining = max_data_bytes;
2234         out_of_space = False;
2235
2236         for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
2237                 bool got_exact_match = False;
2238
2239                 /* this is a heuristic to avoid seeking the dirptr except when
2240                         absolutely necessary. It allows for a filename of about 40 chars */
2241                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2242                         out_of_space = True;
2243                         finished = False;
2244                 } else {
2245                         finished = !get_lanman2_dir_entry(ctx,
2246                                         conn,
2247                                         req->flags2,
2248                                         mask,dirtype,info_level,
2249                                         requires_resume_key,dont_descend,
2250                                         ask_sharemode,
2251                                         &p,pdata,data_end,
2252                                         space_remaining, &out_of_space,
2253                                         &got_exact_match,
2254                                         &last_entry_off, ea_list);
2255                 }
2256
2257                 if (finished && out_of_space)
2258                         finished = False;
2259
2260                 if (!finished && !out_of_space)
2261                         numentries++;
2262
2263                 /*
2264                  * As an optimisation if we know we aren't looking
2265                  * for a wildcard name (ie. the name matches the wildcard exactly)
2266                  * then we can finish on any (first) match.
2267                  * This speeds up large directory searches. JRA.
2268                  */
2269
2270                 if(got_exact_match)
2271                         finished = True;
2272
2273                 /* Ensure space_remaining never goes -ve. */
2274                 if (PTR_DIFF(p,pdata) > max_data_bytes) {
2275                         space_remaining = 0;
2276                         out_of_space = true;
2277                 } else {
2278                         space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2279                 }
2280         }
2281
2282         /* Check if we can close the dirptr */
2283         if(close_after_first || (finished && close_if_end)) {
2284                 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
2285                 dptr_close(&dptr_num);
2286         }
2287
2288         /*
2289          * If there are no matching entries we must return ERRDOS/ERRbadfile -
2290          * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2291          * the protocol level is less than NT1. Tested with smbclient. JRA.
2292          * This should fix the OS/2 client bug #2335.
2293          */
2294
2295         if(numentries == 0) {
2296                 dptr_close(&dptr_num);
2297                 if (Protocol < PROTOCOL_NT1) {
2298                         reply_doserror(req, ERRDOS, ERRnofiles);
2299                         return;
2300                 } else {
2301                         reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
2302                                         ERRDOS, ERRbadfile);
2303                         return;
2304                 }
2305         }
2306
2307         /* At this point pdata points to numentries directory entries. */
2308
2309         /* Set up the return parameter block */
2310         SSVAL(params,0,dptr_num);
2311         SSVAL(params,2,numentries);
2312         SSVAL(params,4,finished);
2313         SSVAL(params,6,0); /* Never an EA error */
2314         SSVAL(params,8,last_entry_off);
2315
2316         send_trans2_replies(conn, req, params, 10, pdata, PTR_DIFF(p,pdata),
2317                             max_data_bytes);
2318
2319         if ((! *directory) && dptr_path(dptr_num)) {
2320                 directory = talloc_strdup(talloc_tos(),dptr_path(dptr_num));
2321                 if (!directory) {
2322                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2323                 }
2324         }
2325
2326         DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2327                 smb_fn_name(req->cmd),
2328                 mask, directory, dirtype, numentries ) );
2329
2330         /*
2331          * Force a name mangle here to ensure that the
2332          * mask as an 8.3 name is top of the mangled cache.
2333          * The reasons for this are subtle. Don't remove
2334          * this code unless you know what you are doing
2335          * (see PR#13758). JRA.
2336          */
2337
2338         if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
2339                 char mangled_name[13];
2340                 name_to_8_3(mask, mangled_name, True, conn->params);
2341         }
2342
2343         return;
2344 }
2345
2346 /****************************************************************************
2347  Reply to a TRANS2_FINDNEXT.
2348 ****************************************************************************/
2349
2350 static void call_trans2findnext(connection_struct *conn,
2351                                 struct smb_request *req,
2352                                 char **pparams, int total_params,
2353                                 char **ppdata, int total_data,
2354                                 unsigned int max_data_bytes)
2355 {
2356         /* We must be careful here that we don't return more than the
2357                 allowed number of data bytes. If this means returning fewer than
2358                 maxentries then so be it. We assume that the redirector has
2359                 enough room for the fixed number of parameter bytes it has
2360                 requested. */
2361         char *params = *pparams;
2362         char *pdata = *ppdata;
2363         char *data_end;
2364         int dptr_num;
2365         int maxentries;
2366         uint16 info_level;
2367         uint32 resume_key;
2368         uint16 findnext_flags;
2369         bool close_after_request;
2370         bool close_if_end;
2371         bool requires_resume_key;
2372         bool continue_bit;
2373         bool mask_contains_wcard = False;
2374         char *resume_name = NULL;
2375         const char *mask = NULL;
2376         const char *directory = NULL;
2377         char *p = NULL;
2378         uint16 dirtype;
2379         int numentries = 0;
2380         int i, last_entry_off=0;
2381         bool finished = False;
2382         bool dont_descend = False;
2383         bool out_of_space = False;
2384         int space_remaining;
2385         struct ea_list *ea_list = NULL;
2386         NTSTATUS ntstatus = NT_STATUS_OK;
2387         bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2388         TALLOC_CTX *ctx = talloc_tos();
2389
2390         if (total_params < 13) {
2391                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2392                 return;
2393         }
2394
2395         dptr_num = SVAL(params,0);
2396         maxentries = SVAL(params,2);
2397         info_level = SVAL(params,4);
2398         resume_key = IVAL(params,6);
2399         findnext_flags = SVAL(params,10);
2400         close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
2401         close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2402         requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2403         continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
2404
2405         srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
2406                               params+12,
2407                               total_params - 12, STR_TERMINATE, &ntstatus,
2408                               &mask_contains_wcard);
2409         if (!NT_STATUS_IS_OK(ntstatus)) {
2410                 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2411                    complain (it thinks we're asking for the directory above the shared
2412                    path or an invalid name). Catch this as the resume name is only compared, never used in
2413                    a file access. JRA. */
2414                 srvstr_pull_talloc(ctx, params, req->flags2,
2415                                 &resume_name, params+12,
2416                                 total_params - 12,
2417                                 STR_TERMINATE);
2418
2419                 if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
2420                         reply_nterror(req, ntstatus);
2421                         return;
2422                 }
2423         }
2424
2425         DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2426 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2427 resume_key = %d resume name = %s continue=%d level = %d\n",
2428                 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end, 
2429                 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
2430
2431         if (!maxentries) {
2432                 /* W2K3 seems to treat zero as 1. */
2433                 maxentries = 1;
2434         }
2435
2436         switch (info_level) {
2437                 case SMB_FIND_INFO_STANDARD:
2438                 case SMB_FIND_EA_SIZE:
2439                 case SMB_FIND_EA_LIST:
2440                 case SMB_FIND_FILE_DIRECTORY_INFO:
2441                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2442                 case SMB_FIND_FILE_NAMES_INFO:
2443                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2444                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2445                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2446                         break;
2447                 case SMB_FIND_FILE_UNIX:
2448                 case SMB_FIND_FILE_UNIX_INFO2:
2449                         /* Always use filesystem for UNIX mtime query. */
2450                         ask_sharemode = false;
2451                         if (!lp_unix_extensions()) {
2452                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2453                                 return;
2454                         }
2455                         break;
2456                 default:
2457                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2458                         return;
2459         }
2460
2461         if (info_level == SMB_FIND_EA_LIST) {
2462                 uint32 ea_size;
2463
2464                 if (total_data < 4) {
2465                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2466                         return;
2467                 }
2468
2469                 ea_size = IVAL(pdata,0);
2470                 if (ea_size != total_data) {
2471                         DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2472 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2473                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2474                         return;
2475                 }
2476
2477                 if (!lp_ea_support(SNUM(conn))) {
2478                         reply_doserror(req, ERRDOS, ERReasnotsupported);
2479                         return;
2480                 }
2481
2482                 /* Pull out the list of names. */
2483                 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2484                 if (!ea_list) {
2485                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2486                         return;
2487                 }
2488         }
2489
2490         *ppdata = (char *)SMB_REALLOC(
2491                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2492         if(*ppdata == NULL) {
2493                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2494                 return;
2495         }
2496
2497         pdata = *ppdata;
2498         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2499
2500         /* Realloc the params space */
2501         *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
2502         if(*pparams == NULL ) {
2503                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2504                 return;
2505         }
2506
2507         params = *pparams;
2508
2509         /* Check that the dptr is valid */
2510         if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
2511                 reply_doserror(req, ERRDOS, ERRnofiles);
2512                 return;
2513         }
2514
2515         string_set(&conn->dirpath,dptr_path(dptr_num));
2516
2517         /* Get the wildcard mask from the dptr */
2518         if((p = dptr_wcard(dptr_num))== NULL) {
2519                 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
2520                 reply_doserror(req, ERRDOS, ERRnofiles);
2521                 return;
2522         }
2523
2524         mask = p;
2525         directory = conn->dirpath;
2526
2527         /* Get the attr mask from the dptr */
2528         dirtype = dptr_attr(dptr_num);
2529
2530         DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2531                 dptr_num, mask, dirtype,
2532                 (long)conn->dirptr,
2533                 dptr_TellDir(conn->dirptr)));
2534
2535         /* Initialize per TRANS2_FIND_NEXT operation data */
2536         dptr_init_search_op(conn->dirptr);
2537
2538         /* We don't need to check for VOL here as this is returned by
2539                 a different TRANS2 call. */
2540
2541         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
2542         if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2543                 dont_descend = True;
2544
2545         p = pdata;
2546         space_remaining = max_data_bytes;
2547         out_of_space = False;
2548
2549         /*
2550          * Seek to the correct position. We no longer use the resume key but
2551          * depend on the last file name instead.
2552          */
2553
2554         if(*resume_name && !continue_bit) {
2555                 SMB_STRUCT_STAT st;
2556
2557                 long current_pos = 0;
2558                 /*
2559                  * Remember, name_to_8_3 is called by
2560                  * get_lanman2_dir_entry(), so the resume name
2561                  * could be mangled. Ensure we check the unmangled name.
2562                  */
2563
2564                 if (mangle_is_mangled(resume_name, conn->params)) {
2565                         char *new_resume_name = NULL;
2566                         mangle_lookup_name_from_8_3(ctx,
2567                                                 resume_name,
2568                                                 &new_resume_name,
2569                                                 conn->params);
2570                         if (new_resume_name) {
2571                                 resume_name = new_resume_name;
2572                         }
2573                 }
2574
2575                 /*
2576                  * Fix for NT redirector problem triggered by resume key indexes
2577                  * changing between directory scans. We now return a resume key of 0
2578                  * and instead look for the filename to continue from (also given
2579                  * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2580                  * findfirst/findnext (as is usual) then the directory pointer
2581                  * should already be at the correct place.
2582                  */
2583
2584                 finished = !dptr_SearchDir(conn->dirptr, resume_name, &current_pos, &st);
2585         } /* end if resume_name && !continue_bit */
2586
2587         for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
2588                 bool got_exact_match = False;
2589
2590                 /* this is a heuristic to avoid seeking the dirptr except when 
2591                         absolutely necessary. It allows for a filename of about 40 chars */
2592                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2593                         out_of_space = True;
2594                         finished = False;
2595                 } else {
2596                         finished = !get_lanman2_dir_entry(ctx,
2597                                                 conn,
2598                                                 req->flags2,
2599                                                 mask,dirtype,info_level,
2600                                                 requires_resume_key,dont_descend,
2601                                                 ask_sharemode,
2602                                                 &p,pdata,data_end,
2603                                                 space_remaining, &out_of_space,
2604                                                 &got_exact_match,
2605                                                 &last_entry_off, ea_list);
2606                 }
2607
2608                 if (finished && out_of_space)
2609                         finished = False;
2610
2611                 if (!finished && !out_of_space)
2612                         numentries++;
2613
2614                 /*
2615                  * As an optimisation if we know we aren't looking
2616                  * for a wildcard name (ie. the name matches the wildcard exactly)
2617                  * then we can finish on any (first) match.
2618                  * This speeds up large directory searches. JRA.
2619                  */
2620
2621                 if(got_exact_match)
2622                         finished = True;
2623
2624                 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2625         }
2626
2627         DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2628                 smb_fn_name(req->cmd),
2629                 mask, directory, dirtype, numentries ) );
2630
2631         /* Check if we can close the dirptr */
2632         if(close_after_request || (finished && close_if_end)) {
2633                 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2634                 dptr_close(&dptr_num); /* This frees up the saved mask */
2635         }
2636
2637         /* Set up the return parameter block */
2638         SSVAL(params,0,numentries);
2639         SSVAL(params,2,finished);
2640         SSVAL(params,4,0); /* Never an EA error */
2641         SSVAL(params,6,last_entry_off);
2642
2643         send_trans2_replies(conn, req, params, 8, pdata, PTR_DIFF(p,pdata),
2644                             max_data_bytes);
2645
2646         return;
2647 }
2648
2649 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
2650 {
2651         E_md4hash(lp_servicename(SNUM(conn)),objid);
2652         return objid;
2653 }
2654
2655 static void samba_extended_info_version(struct smb_extended_info *extended_info)
2656 {
2657         SMB_ASSERT(extended_info != NULL);
2658
2659         extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
2660         extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
2661                                        | ((SAMBA_VERSION_MINOR & 0xff) << 16)
2662                                        | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
2663 #ifdef SAMBA_VERSION_REVISION
2664         extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
2665 #endif
2666         extended_info->samba_subversion = 0;
2667 #ifdef SAMBA_VERSION_RC_RELEASE
2668         extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
2669 #else
2670 #ifdef SAMBA_VERSION_PRE_RELEASE
2671         extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
2672 #endif
2673 #endif
2674 #ifdef SAMBA_VERSION_VENDOR_PATCH
2675         extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
2676 #endif
2677         extended_info->samba_gitcommitdate = 0;
2678 #ifdef SAMBA_VERSION_GIT_COMMIT_TIME
2679         unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_GIT_COMMIT_TIME);
2680 #endif
2681
2682         memset(extended_info->samba_version_string, 0,
2683                sizeof(extended_info->samba_version_string));
2684
2685         snprintf (extended_info->samba_version_string,
2686                   sizeof(extended_info->samba_version_string),
2687                   "%s", samba_version_string());
2688 }
2689
2690 NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
2691                          TALLOC_CTX *mem_ctx,
2692                          uint16_t info_level,
2693                          SMB_STRUCT_STAT st,
2694                          uint16_t flags2,
2695                          unsigned int max_data_bytes,
2696                          char **ppdata,
2697                          int *ret_data_len)
2698 {
2699         char *pdata, *end_data;
2700         int data_len = 0, len;
2701         const char *vname = volume_label(SNUM(conn));
2702         int snum = SNUM(conn);
2703         char *fstype = lp_fstype(SNUM(conn));
2704         uint32 additional_flags = 0;
2705
2706         if (IS_IPC(conn)) {
2707                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
2708                         DEBUG(0,("smbd_do_qfsinfo: not an allowed "
2709                                 "info level (0x%x) on IPC$.\n",
2710                                 (unsigned int)info_level));
2711                         return NT_STATUS_ACCESS_DENIED;
2712                 }
2713         }
2714
2715         DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
2716
2717         *ppdata = (char *)SMB_REALLOC(
2718                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2719         if (*ppdata == NULL) {
2720                 return NT_STATUS_NO_MEMORY;
2721         }
2722
2723         pdata = *ppdata;
2724         memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2725         end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2726
2727         switch (info_level) {
2728                 case SMB_INFO_ALLOCATION:
2729                 {
2730                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2731                         data_len = 18;
2732                         if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2733                                 return map_nt_error_from_unix(errno);
2734                         }
2735
2736                         block_size = lp_block_size(snum);
2737                         if (bsize < block_size) {
2738                                 uint64_t factor = block_size/bsize;
2739                                 bsize = block_size;
2740                                 dsize /= factor;
2741                                 dfree /= factor;
2742                         }
2743                         if (bsize > block_size) {
2744                                 uint64_t factor = bsize/block_size;
2745                                 bsize = block_size;
2746                                 dsize *= factor;
2747                                 dfree *= factor;
2748                         }
2749                         bytes_per_sector = 512;
2750                         sectors_per_unit = bsize/bytes_per_sector;
2751
2752                         DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2753 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2754                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2755
2756                         SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
2757                         SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2758                         SIVAL(pdata,l1_cUnit,dsize);
2759                         SIVAL(pdata,l1_cUnitAvail,dfree);
2760                         SSVAL(pdata,l1_cbSector,bytes_per_sector);
2761                         break;
2762                 }
2763
2764                 case SMB_INFO_VOLUME:
2765                         /* Return volume name */
2766                         /* 
2767                          * Add volume serial number - hash of a combination of
2768                          * the called hostname and the service name.
2769                          */
2770                         SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2771                         /*
2772                          * Win2k3 and previous mess this up by sending a name length
2773                          * one byte short. I believe only older clients (OS/2 Win9x) use
2774                          * this call so try fixing this by adding a terminating null to
2775                          * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2776                          */
2777                         len = srvstr_push(
2778                                 pdata, flags2,
2779                                 pdata+l2_vol_szVolLabel, vname,
2780                                 PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
2781                                 STR_NOALIGN|STR_TERMINATE);
2782                         SCVAL(pdata,l2_vol_cch,len);
2783                         data_len = l2_vol_szVolLabel + len;
2784                         DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n",
2785                                  (unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
2786                                  len, vname));
2787                         break;
2788
2789                 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2790                 case SMB_FS_ATTRIBUTE_INFORMATION:
2791
2792                         additional_flags = 0;
2793 #if defined(HAVE_SYS_QUOTAS)
2794                         additional_flags |= FILE_VOLUME_QUOTAS;
2795 #endif
2796
2797                         if(lp_nt_acl_support(SNUM(conn))) {
2798                                 additional_flags |= FILE_PERSISTENT_ACLS;
2799                         }
2800
2801                         /* Capabilities are filled in at connection time through STATVFS call */
2802                         additional_flags |= conn->fs_capabilities;
2803
2804                         SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2805                                 FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
2806                                 additional_flags); /* FS ATTRIBUTES */
2807
2808                         SIVAL(pdata,4,255); /* Max filename component length */
2809                         /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2810                                 and will think we can't do long filenames */
2811                         len = srvstr_push(pdata, flags2, pdata+12, fstype,
2812                                           PTR_DIFF(end_data, pdata+12),
2813                                           STR_UNICODE);
2814                         SIVAL(pdata,8,len);
2815                         data_len = 12 + len;
2816                         break;
2817
2818                 case SMB_QUERY_FS_LABEL_INFO:
2819                 case SMB_FS_LABEL_INFORMATION:
2820                         len = srvstr_push(pdata, flags2, pdata+4, vname,
2821                                           PTR_DIFF(end_data, pdata+4), 0);
2822                         data_len = 4 + len;
2823                         SIVAL(pdata,0,len);
2824                         break;
2825
2826                 case SMB_QUERY_FS_VOLUME_INFO:      
2827                 case SMB_FS_VOLUME_INFORMATION:
2828
2829                         /* 
2830                          * Add volume serial number - hash of a combination of
2831                          * the called hostname and the service name.
2832                          */
2833                         SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ 
2834                                 (str_checksum(get_local_machine_name())<<16));
2835
2836                         /* Max label len is 32 characters. */
2837                         len = srvstr_push(pdata, flags2, pdata+18, vname,
2838                                           PTR_DIFF(end_data, pdata+18),
2839                                           STR_UNICODE);
2840                         SIVAL(pdata,12,len);
2841                         data_len = 18+len;
2842
2843                         DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
2844                                 (int)strlen(vname),vname, lp_servicename(snum)));
2845                         break;
2846
2847                 case SMB_QUERY_FS_SIZE_INFO:
2848                 case SMB_FS_SIZE_INFORMATION:
2849                 {
2850                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2851                         data_len = 24;
2852                         if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2853                                 return map_nt_error_from_unix(errno);
2854                         }
2855                         block_size = lp_block_size(snum);
2856                         if (bsize < block_size) {
2857                                 uint64_t factor = block_size/bsize;
2858                                 bsize = block_size;
2859                                 dsize /= factor;
2860                                 dfree /= factor;
2861                         }
2862                         if (bsize > block_size) {
2863                                 uint64_t factor = bsize/block_size;
2864                                 bsize = block_size;
2865                                 dsize *= factor;
2866                                 dfree *= factor;
2867                         }
2868                         bytes_per_sector = 512;
2869                         sectors_per_unit = bsize/bytes_per_sector;
2870                         DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2871 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2872                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2873                         SBIG_UINT(pdata,0,dsize);
2874                         SBIG_UINT(pdata,8,dfree);
2875                         SIVAL(pdata,16,sectors_per_unit);
2876                         SIVAL(pdata,20,bytes_per_sector);
2877                         break;
2878                 }
2879
2880                 case SMB_FS_FULL_SIZE_INFORMATION:
2881                 {
2882                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2883                         data_len = 32;
2884                         if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2885                                 return map_nt_error_from_unix(errno);
2886                         }
2887                         block_size = lp_block_size(snum);
2888                         if (bsize < block_size) {
2889                                 uint64_t factor = block_size/bsize;
2890                                 bsize = block_size;
2891                                 dsize /= factor;
2892                                 dfree /= factor;
2893                         }
2894                         if (bsize > block_size) {
2895                                 uint64_t factor = bsize/block_size;
2896                                 bsize = block_size;
2897                                 dsize *= factor;
2898                                 dfree *= factor;
2899                         }
2900                         bytes_per_sector = 512;
2901                         sectors_per_unit = bsize/bytes_per_sector;
2902                         DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2903 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2904                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2905                         SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2906                         SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2907                         SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2908                         SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2909                         SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2910                         break;
2911                 }
2912
2913                 case SMB_QUERY_FS_DEVICE_INFO:
2914                 case SMB_FS_DEVICE_INFORMATION:
2915                         data_len = 8;
2916                         SIVAL(pdata,0,0); /* dev type */
2917                         SIVAL(pdata,4,0); /* characteristics */
2918                         break;
2919
2920 #ifdef HAVE_SYS_QUOTAS
2921                 case SMB_FS_QUOTA_INFORMATION:
2922                 /* 
2923                  * what we have to send --metze:
2924                  *
2925                  * Unknown1:            24 NULL bytes
2926                  * Soft Quota Treshold: 8 bytes seems like uint64_t or so
2927                  * Hard Quota Limit:    8 bytes seems like uint64_t or so
2928                  * Quota Flags:         2 byte :
2929                  * Unknown3:            6 NULL bytes
2930                  *
2931                  * 48 bytes total
2932                  * 
2933                  * details for Quota Flags:
2934                  * 
2935                  * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2936                  * 0x0010 Log Warn:  log if the user exceeds his Soft Quota
2937                  * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2938                  * 0x0001 Enable Quotas: enable quota for this fs
2939                  *
2940                  */
2941                 {
2942                         /* we need to fake up a fsp here,
2943                          * because its not send in this call
2944                          */
2945                         files_struct fsp;
2946                         SMB_NTQUOTA_STRUCT quotas;
2947
2948                         ZERO_STRUCT(fsp);
2949                         ZERO_STRUCT(quotas);
2950
2951                         fsp.conn = conn;
2952                         fsp.fnum = -1;
2953
2954                         /* access check */
2955                         if (conn->server_info->utok.uid != sec_initial_uid()) {
2956                                 DEBUG(0,("set_user_quota: access_denied "
2957                                          "service [%s] user [%s]\n",
2958                                          lp_servicename(SNUM(conn)),
2959                                          conn->server_info->unix_name));
2960                                 return NT_STATUS_ACCESS_DENIED;
2961                         }
2962
2963                         if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
2964                                 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2965                                 return map_nt_error_from_unix(errno);
2966                         }
2967
2968                         data_len = 48;
2969
2970                         DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
2971                                   lp_servicename(SNUM(conn))));
2972
2973                         /* Unknown1 24 NULL bytes*/
2974                         SBIG_UINT(pdata,0,(uint64_t)0);
2975                         SBIG_UINT(pdata,8,(uint64_t)0);
2976                         SBIG_UINT(pdata,16,(uint64_t)0);
2977
2978                         /* Default Soft Quota 8 bytes */
2979                         SBIG_UINT(pdata,24,quotas.softlim);
2980
2981                         /* Default Hard Quota 8 bytes */
2982                         SBIG_UINT(pdata,32,quotas.hardlim);
2983
2984                         /* Quota flag 2 bytes */
2985                         SSVAL(pdata,40,quotas.qflags);
2986
2987                         /* Unknown3 6 NULL bytes */
2988                         SSVAL(pdata,42,0);
2989                         SIVAL(pdata,44,0);
2990
2991                         break;
2992                 }
2993 #endif /* HAVE_SYS_QUOTAS */
2994                 case SMB_FS_OBJECTID_INFORMATION:
2995                 {
2996                         unsigned char objid[16];
2997                         struct smb_extended_info extended_info;
2998                         memcpy(pdata,create_volume_objectid(conn, objid),16);
2999                         samba_extended_info_version (&extended_info);
3000                         SIVAL(pdata,16,extended_info.samba_magic);
3001                         SIVAL(pdata,20,extended_info.samba_version);
3002                         SIVAL(pdata,24,extended_info.samba_subversion);
3003                         SBIG_UINT(pdata,28,extended_info.samba_gitcommitdate);
3004                         memcpy(pdata+36,extended_info.samba_version_string,28);
3005                         data_len = 64;
3006                         break;
3007                 }
3008
3009                 /*
3010                  * Query the version and capabilities of the CIFS UNIX extensions
3011                  * in use.
3012                  */
3013
3014                 case SMB_QUERY_CIFS_UNIX_INFO:
3015                 {
3016                         bool large_write = lp_min_receive_file_size() &&
3017                                         !srv_is_signing_active(smbd_server_conn);
3018                         bool large_read = !srv_is_signing_active(smbd_server_conn);
3019                         int encrypt_caps = 0;
3020
3021                         if (!lp_unix_extensions()) {
3022                                 return NT_STATUS_INVALID_LEVEL;
3023                         }
3024
3025                         switch (conn->encrypt_level) {
3026                         case 0:
3027                                 encrypt_caps = 0;
3028                                 break;
3029                         case 1:
3030                         case Auto:
3031                                 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP;
3032                                 break;
3033                         case Required:
3034                                 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP|
3035                                                 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP;
3036                                 large_write = false;
3037                                 large_read = false;
3038                                 break;
3039                         }
3040
3041                         data_len = 12;
3042                         SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
3043                         SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
3044
3045                         /* We have POSIX ACLs, pathname, encryption, 
3046                          * large read/write, and locking capability. */
3047
3048                         SBIG_UINT(pdata,4,((uint64_t)(
3049                                         CIFS_UNIX_POSIX_ACLS_CAP|
3050                                         CIFS_UNIX_POSIX_PATHNAMES_CAP|
3051                                         CIFS_UNIX_FCNTL_LOCKS_CAP|
3052                                         CIFS_UNIX_EXTATTR_CAP|
3053                                         CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP|
3054                                         encrypt_caps|
3055                                         (large_read ? CIFS_UNIX_LARGE_READ_CAP : 0) |
3056                                         (large_write ?
3057                                         CIFS_UNIX_LARGE_WRITE_CAP : 0))));
3058                         break;
3059                 }
3060
3061                 case SMB_QUERY_POSIX_FS_INFO:
3062                 {
3063                         int rc;
3064                         vfs_statvfs_struct svfs;
3065
3066                         if (!lp_unix_extensions()) {
3067                                 return NT_STATUS_INVALID_LEVEL;
3068                         }
3069
3070                         rc = SMB_VFS_STATVFS(conn, ".", &svfs);
3071
3072                         if (!rc) {
3073                                 data_len = 56;
3074                                 SIVAL(pdata,0,svfs.OptimalTransferSize);
3075                                 SIVAL(pdata,4,svfs.BlockSize);
3076                                 SBIG_UINT(pdata,8,svfs.TotalBlocks);
3077                                 SBIG_UINT(pdata,16,svfs.BlocksAvail);
3078                                 SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
3079                                 SBIG_UINT(pdata,32,svfs.TotalFileNodes);
3080                                 SBIG_UINT(pdata,40,svfs.FreeFileNodes);
3081                                 SBIG_UINT(pdata,48,svfs.FsIdentifier);
3082                                 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
3083 #ifdef EOPNOTSUPP
3084                         } else if (rc == EOPNOTSUPP) {
3085                                 return NT_STATUS_INVALID_LEVEL;
3086 #endif /* EOPNOTSUPP */
3087                         } else {
3088                                 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
3089                                 return NT_STATUS_DOS(ERRSRV, ERRerror);
3090                         }
3091                         break;
3092                 }
3093
3094                 case SMB_QUERY_POSIX_WHOAMI:
3095                 {
3096                         uint32_t flags = 0;
3097                         uint32_t sid_bytes;
3098                         int i;
3099
3100                         if (!lp_unix_extensions()) {
3101                                 return NT_STATUS_INVALID_LEVEL;
3102                         }
3103
3104                         if (max_data_bytes < 40) {
3105                                 return NT_STATUS_BUFFER_TOO_SMALL;
3106                         }
3107
3108                         /* We ARE guest if global_sid_Builtin_Guests is
3109                          * in our list of SIDs.
3110                          */
3111                         if (nt_token_check_sid(&global_sid_Builtin_Guests,
3112                                                conn->server_info->ptok)) {
3113                                 flags |= SMB_WHOAMI_GUEST;
3114                         }
3115
3116                         /* We are NOT guest if global_sid_Authenticated_Users
3117                          * is in our list of SIDs.
3118                          */
3119                         if (nt_token_check_sid(&global_sid_Authenticated_Users,
3120                                                conn->server_info->ptok)) {
3121                                 flags &= ~SMB_WHOAMI_GUEST;
3122                         }
3123
3124                         /* NOTE: 8 bytes for UID/GID, irrespective of native
3125                          * platform size. This matches
3126                          * SMB_QUERY_FILE_UNIX_BASIC and friends.
3127                          */
3128                         data_len = 4 /* flags */
3129                             + 4 /* flag mask */
3130                             + 8 /* uid */
3131                             + 8 /* gid */
3132                             + 4 /* ngroups */
3133                             + 4 /* num_sids */
3134                             + 4 /* SID bytes */
3135                             + 4 /* pad/reserved */
3136                             + (conn->server_info->utok.ngroups * 8)
3137                                 /* groups list */
3138                             + (conn->server_info->ptok->num_sids *
3139                                     SID_MAX_SIZE)
3140                                 /* SID list */;
3141
3142                         SIVAL(pdata, 0, flags);
3143                         SIVAL(pdata, 4, SMB_WHOAMI_MASK);
3144                         SBIG_UINT(pdata, 8,
3145                                   (uint64_t)conn->server_info->utok.uid);
3146                         SBIG_UINT(pdata, 16,
3147                                   (uint64_t)conn->server_info->utok.gid);
3148
3149
3150                         if (data_len >= max_data_bytes) {
3151                                 /* Potential overflow, skip the GIDs and SIDs. */
3152
3153                                 SIVAL(pdata, 24, 0); /* num_groups */
3154                                 SIVAL(pdata, 28, 0); /* num_sids */
3155                                 SIVAL(pdata, 32, 0); /* num_sid_bytes */
3156                                 SIVAL(pdata, 36, 0); /* reserved */
3157
3158                                 data_len = 40;
3159                                 break;
3160                         }
3161
3162                         SIVAL(pdata, 24, conn->server_info->utok.ngroups);
3163                         SIVAL(pdata, 28, conn->server_info->num_sids);
3164
3165                         /* We walk the SID list twice, but this call is fairly
3166                          * infrequent, and I don't expect that it's performance
3167                          * sensitive -- jpeach
3168                          */
3169                         for (i = 0, sid_bytes = 0;
3170                              i < conn->server_info->ptok->num_sids; ++i) {
3171                                 sid_bytes += ndr_size_dom_sid(
3172                                         &conn->server_info->ptok->user_sids[i],
3173                                         NULL, 
3174                                         0);
3175                         }
3176
3177                         /* SID list byte count */
3178                         SIVAL(pdata, 32, sid_bytes);
3179
3180                         /* 4 bytes pad/reserved - must be zero */
3181                         SIVAL(pdata, 36, 0);
3182                         data_len = 40;
3183
3184                         /* GID list */
3185                         for (i = 0; i < conn->server_info->utok.ngroups; ++i) {
3186                                 SBIG_UINT(pdata, data_len,
3187                                           (uint64_t)conn->server_info->utok.groups[i]);
3188                                 data_len += 8;
3189                         }
3190
3191                         /* SID list */
3192                         for (i = 0;
3193                             i < conn->server_info->ptok->num_sids; ++i) {
3194                                 int sid_len = ndr_size_dom_sid(
3195                                         &conn->server_info->ptok->user_sids[i],
3196                                         NULL,
3197                                         0);
3198
3199                                 sid_linearize(pdata + data_len, sid_len,
3200                                     &conn->server_info->ptok->user_sids[i]);
3201                                 data_len += sid_len;
3202                         }
3203
3204                         break;
3205                 }
3206
3207                 case SMB_MAC_QUERY_FS_INFO:
3208                         /*
3209                          * Thursby MAC extension... ONLY on NTFS filesystems
3210                          * once we do streams then we don't need this
3211                          */
3212                         if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
3213                                 data_len = 88;
3214                                 SIVAL(pdata,84,0x100); /* Don't support mac... */
3215                                 break;
3216                         }
3217                         /* drop through */
3218                 default:
3219                         return NT_STATUS_INVALID_LEVEL;
3220         }
3221
3222         *ret_data_len = data_len;
3223         return NT_STATUS_OK;
3224 }
3225
3226 /****************************************************************************
3227  Reply to a TRANS2_QFSINFO (query filesystem info).
3228 ****************************************************************************/
3229
3230 static void call_trans2qfsinfo(connection_struct *conn,
3231                                struct smb_request *req,
3232                                char **pparams, int total_params,
3233                                char **ppdata, int total_data,
3234                                unsigned int max_data_bytes)
3235 {
3236         char *params = *pparams;
3237         uint16_t info_level;
3238         int data_len = 0;
3239         SMB_STRUCT_STAT st;
3240         NTSTATUS status;
3241
3242         if (total_params < 2) {
3243                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3244                 return;
3245         }
3246
3247         info_level = SVAL(params,0);
3248
3249         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
3250                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
3251                         DEBUG(0,("call_trans2qfsinfo: encryption required "
3252                                 "and info level 0x%x sent.\n",
3253                                 (unsigned int)info_level));
3254                         exit_server_cleanly("encryption required "
3255                                 "on connection");
3256                         return;
3257                 }
3258         }
3259
3260         DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
3261
3262         if(vfs_stat_smb_fname(conn,".",&st)!=0) {
3263                 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
3264                 reply_doserror(req, ERRSRV, ERRinvdevice);
3265                 return;
3266         }
3267
3268         status = smbd_do_qfsinfo(conn, req,
3269                                  info_level, st,
3270                                  req->flags2,
3271                                  max_data_bytes,
3272                                  ppdata, &data_len);
3273         if (!NT_STATUS_IS_OK(status)) {
3274                 reply_nterror(req, status);
3275                 return;
3276         }
3277
3278         send_trans2_replies(conn, req, params, 0, *ppdata, data_len,
3279                             max_data_bytes);
3280
3281         DEBUG( 4, ( "%s info_level = %d\n",
3282                     smb_fn_name(req->cmd), info_level) );
3283
3284         return;
3285 }
3286
3287 /****************************************************************************
3288  Reply to a TRANS2_SETFSINFO (set filesystem info).
3289 ****************************************************************************/
3290
3291 static void call_trans2setfsinfo(connection_struct *conn,
3292                                  struct smb_request *req,
3293                                  char **pparams, int total_params,
3294                                  char **ppdata, int total_data,
3295                                  unsigned int max_data_bytes)
3296 {
3297         char *pdata = *ppdata;
3298         char *params = *pparams;
3299         uint16 info_level;
3300
3301         DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn))));
3302
3303         /*  */
3304         if (total_params < 4) {
3305                 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
3306                         total_params));
3307                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3308                 return;
3309         }
3310
3311         info_level = SVAL(params,2);
3312
3313         if (IS_IPC(conn)) {
3314                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION &&
3315                                 info_level != SMB_SET_CIFS_UNIX_INFO) {
3316                         DEBUG(0,("call_trans2setfsinfo: not an allowed "
3317                                 "info level (0x%x) on IPC$.\n",
3318                                 (unsigned int)info_level));
3319                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
3320                         return;
3321                 }
3322         }
3323
3324         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
3325                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
3326                         DEBUG(0,("call_trans2setfsinfo: encryption required "
3327                                 "and info level 0x%x sent.\n",
3328                                 (unsigned int)info_level));
3329                         exit_server_cleanly("encryption required "
3330                                 "on connection");
3331                         return;
3332                 }
3333         }
3334
3335         switch(info_level) {
3336                 case SMB_SET_CIFS_UNIX_INFO:
3337                         {
3338                                 uint16 client_unix_major;
3339                                 uint16 client_unix_minor;
3340                                 uint32 client_unix_cap_low;
3341                                 uint32 client_unix_cap_high;
3342
3343                                 if (!lp_unix_extensions()) {
3344                                         reply_nterror(req,
3345                                                       NT_STATUS_INVALID_LEVEL);
3346                                         return;
3347                                 }
3348
3349                                 /* There should be 12 bytes of capabilities set. */
3350                                 if (total_data < 8) {
3351                                         reply_nterror(
3352                                                 req,
3353                                                 NT_STATUS_INVALID_PARAMETER);
3354                                         return;
3355                                 }
3356                                 client_unix_major = SVAL(pdata,0);
3357                                 client_unix_minor = SVAL(pdata,2);
3358                                 client_unix_cap_low = IVAL(pdata,4);
3359                                 client_unix_cap_high = IVAL(pdata,8);
3360                                 /* Just print these values for now. */
3361                                 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
3362 cap_low = 0x%x, cap_high = 0x%x\n",
3363                                         (unsigned int)client_unix_major,
3364                                         (unsigned int)client_unix_minor,
3365                                         (unsigned int)client_unix_cap_low,
3366                                         (unsigned int)client_unix_cap_high ));
3367
3368                                 /* Here is where we must switch to posix pathname processing... */
3369                                 if (client_unix_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
3370                                         lp_set_posix_pathnames();
3371                                         mangle_change_to_posix();
3372                                 }
3373
3374                                 if ((client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
3375                                     !(client_unix_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
3376                                         /* Client that knows how to do posix locks,
3377                                          * but not posix open/mkdir operations. Set a
3378                                          * default type for read/write checks. */
3379
3380                                         lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
3381
3382                                 }
3383                                 break;
3384                         }
3385
3386                 case SMB_REQUEST_TRANSPORT_ENCRYPTION:
3387                         {
3388                                 NTSTATUS status;
3389                                 size_t param_len = 0;
3390                                 size_t data_len = total_data;
3391
3392                                 if (!lp_unix_extensions()) {
3393                                         reply_nterror(
3394                                                 req,
3395                                                 NT_STATUS_INVALID_LEVEL);
3396           &