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