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