759e520866cc90ba3778efbdccb03efce37f619d
[tprouty/samba.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         /* Initialize per TRANS2_FIND_FIRST operation data */
2068         dptr_init_search_op(conn->dirptr);
2069
2070         /* We don't need to check for VOL here as this is returned by
2071                 a different TRANS2 call. */
2072
2073         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
2074         if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2075                 dont_descend = True;
2076
2077         p = pdata;
2078         space_remaining = max_data_bytes;
2079         out_of_space = False;
2080
2081         for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
2082                 bool got_exact_match = False;
2083
2084                 /* this is a heuristic to avoid seeking the dirptr except when
2085                         absolutely necessary. It allows for a filename of about 40 chars */
2086                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2087                         out_of_space = True;
2088                         finished = False;
2089                 } else {
2090                         finished = !get_lanman2_dir_entry(ctx,
2091                                         conn,
2092                                         req->flags2,
2093                                         mask,dirtype,info_level,
2094                                         requires_resume_key,dont_descend,
2095                                         ask_sharemode,
2096                                         &p,pdata,data_end,
2097                                         space_remaining, &out_of_space,
2098                                         &got_exact_match,
2099                                         &last_entry_off, ea_list);
2100                 }
2101
2102                 if (finished && out_of_space)
2103                         finished = False;
2104
2105                 if (!finished && !out_of_space)
2106                         numentries++;
2107
2108                 /*
2109                  * As an optimisation if we know we aren't looking
2110                  * for a wildcard name (ie. the name matches the wildcard exactly)
2111                  * then we can finish on any (first) match.
2112                  * This speeds up large directory searches. JRA.
2113                  */
2114
2115                 if(got_exact_match)
2116                         finished = True;
2117
2118                 /* Ensure space_remaining never goes -ve. */
2119                 if (PTR_DIFF(p,pdata) > max_data_bytes) {
2120                         space_remaining = 0;
2121                         out_of_space = true;
2122                 } else {
2123                         space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2124                 }
2125         }
2126
2127         /* Check if we can close the dirptr */
2128         if(close_after_first || (finished && close_if_end)) {
2129                 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
2130                 dptr_close(&dptr_num);
2131         }
2132
2133         /*
2134          * If there are no matching entries we must return ERRDOS/ERRbadfile -
2135          * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
2136          * the protocol level is less than NT1. Tested with smbclient. JRA.
2137          * This should fix the OS/2 client bug #2335.
2138          */
2139
2140         if(numentries == 0) {
2141                 dptr_close(&dptr_num);
2142                 if (Protocol < PROTOCOL_NT1) {
2143                         reply_doserror(req, ERRDOS, ERRnofiles);
2144                         return;
2145                 } else {
2146                         reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
2147                                         ERRDOS, ERRbadfile);
2148                         return;
2149                 }
2150         }
2151
2152         /* At this point pdata points to numentries directory entries. */
2153
2154         /* Set up the return parameter block */
2155         SSVAL(params,0,dptr_num);
2156         SSVAL(params,2,numentries);
2157         SSVAL(params,4,finished);
2158         SSVAL(params,6,0); /* Never an EA error */
2159         SSVAL(params,8,last_entry_off);
2160
2161         send_trans2_replies(conn, req, params, 10, pdata, PTR_DIFF(p,pdata),
2162                             max_data_bytes);
2163
2164         if ((! *directory) && dptr_path(dptr_num)) {
2165                 directory = talloc_strdup(talloc_tos(),dptr_path(dptr_num));
2166                 if (!directory) {
2167                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2168                 }
2169         }
2170
2171         DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2172                 smb_fn_name(req->cmd),
2173                 mask, directory, dirtype, numentries ) );
2174
2175         /*
2176          * Force a name mangle here to ensure that the
2177          * mask as an 8.3 name is top of the mangled cache.
2178          * The reasons for this are subtle. Don't remove
2179          * this code unless you know what you are doing
2180          * (see PR#13758). JRA.
2181          */
2182
2183         if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
2184                 char mangled_name[13];
2185                 name_to_8_3(mask, mangled_name, True, conn->params);
2186         }
2187
2188         return;
2189 }
2190
2191 /****************************************************************************
2192  Reply to a TRANS2_FINDNEXT.
2193 ****************************************************************************/
2194
2195 static void call_trans2findnext(connection_struct *conn,
2196                                 struct smb_request *req,
2197                                 char **pparams, int total_params,
2198                                 char **ppdata, int total_data,
2199                                 unsigned int max_data_bytes)
2200 {
2201         /* We must be careful here that we don't return more than the
2202                 allowed number of data bytes. If this means returning fewer than
2203                 maxentries then so be it. We assume that the redirector has
2204                 enough room for the fixed number of parameter bytes it has
2205                 requested. */
2206         char *params = *pparams;
2207         char *pdata = *ppdata;
2208         char *data_end;
2209         int dptr_num;
2210         int maxentries;
2211         uint16 info_level;
2212         uint32 resume_key;
2213         uint16 findnext_flags;
2214         bool close_after_request;
2215         bool close_if_end;
2216         bool requires_resume_key;
2217         bool continue_bit;
2218         bool mask_contains_wcard = False;
2219         char *resume_name = NULL;
2220         const char *mask = NULL;
2221         const char *directory = NULL;
2222         char *p = NULL;
2223         uint16 dirtype;
2224         int numentries = 0;
2225         int i, last_entry_off=0;
2226         bool finished = False;
2227         bool dont_descend = False;
2228         bool out_of_space = False;
2229         int space_remaining;
2230         struct ea_list *ea_list = NULL;
2231         NTSTATUS ntstatus = NT_STATUS_OK;
2232         bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
2233         TALLOC_CTX *ctx = talloc_tos();
2234
2235         if (total_params < 13) {
2236                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2237                 return;
2238         }
2239
2240         dptr_num = SVAL(params,0);
2241         maxentries = SVAL(params,2);
2242         info_level = SVAL(params,4);
2243         resume_key = IVAL(params,6);
2244         findnext_flags = SVAL(params,10);
2245         close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
2246         close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2247         requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2248         continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
2249
2250         srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
2251                               params+12,
2252                               total_params - 12, STR_TERMINATE, &ntstatus,
2253                               &mask_contains_wcard);
2254         if (!NT_STATUS_IS_OK(ntstatus)) {
2255                 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2256                    complain (it thinks we're asking for the directory above the shared
2257                    path or an invalid name). Catch this as the resume name is only compared, never used in
2258                    a file access. JRA. */
2259                 srvstr_pull_talloc(ctx, params, req->flags2,
2260                                 &resume_name, params+12,
2261                                 total_params - 12,
2262                                 STR_TERMINATE);
2263
2264                 if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
2265                         reply_nterror(req, ntstatus);
2266                         return;
2267                 }
2268         }
2269
2270         DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2271 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2272 resume_key = %d resume name = %s continue=%d level = %d\n",
2273                 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end, 
2274                 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
2275
2276         if (!maxentries) {
2277                 /* W2K3 seems to treat zero as 1. */
2278                 maxentries = 1;
2279         }
2280
2281         switch (info_level) {
2282                 case SMB_FIND_INFO_STANDARD:
2283                 case SMB_FIND_EA_SIZE:
2284                 case SMB_FIND_EA_LIST:
2285                 case SMB_FIND_FILE_DIRECTORY_INFO:
2286                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2287                 case SMB_FIND_FILE_NAMES_INFO:
2288                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2289                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2290                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2291                         break;
2292                 case SMB_FIND_FILE_UNIX:
2293                 case SMB_FIND_FILE_UNIX_INFO2:
2294                         /* Always use filesystem for UNIX mtime query. */
2295                         ask_sharemode = false;
2296                         if (!lp_unix_extensions()) {
2297                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2298                                 return;
2299                         }
2300                         break;
2301                 default:
2302                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2303                         return;
2304         }
2305
2306         if (info_level == SMB_FIND_EA_LIST) {
2307                 uint32 ea_size;
2308
2309                 if (total_data < 4) {
2310                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2311                         return;
2312                 }
2313
2314                 ea_size = IVAL(pdata,0);
2315                 if (ea_size != total_data) {
2316                         DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2317 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2318                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2319                         return;
2320                 }
2321
2322                 if (!lp_ea_support(SNUM(conn))) {
2323                         reply_doserror(req, ERRDOS, ERReasnotsupported);
2324                         return;
2325                 }
2326
2327                 /* Pull out the list of names. */
2328                 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
2329                 if (!ea_list) {
2330                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2331                         return;
2332                 }
2333         }
2334
2335         *ppdata = (char *)SMB_REALLOC(
2336                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2337         if(*ppdata == NULL) {
2338                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2339                 return;
2340         }
2341
2342         pdata = *ppdata;
2343         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2344
2345         /* Realloc the params space */
2346         *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
2347         if(*pparams == NULL ) {
2348                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2349                 return;
2350         }
2351
2352         params = *pparams;
2353
2354         /* Check that the dptr is valid */
2355         if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
2356                 reply_doserror(req, ERRDOS, ERRnofiles);
2357                 return;
2358         }
2359
2360         string_set(&conn->dirpath,dptr_path(dptr_num));
2361
2362         /* Get the wildcard mask from the dptr */
2363         if((p = dptr_wcard(dptr_num))== NULL) {
2364                 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
2365                 reply_doserror(req, ERRDOS, ERRnofiles);
2366                 return;
2367         }
2368
2369         mask = p;
2370         directory = conn->dirpath;
2371
2372         /* Get the attr mask from the dptr */
2373         dirtype = dptr_attr(dptr_num);
2374
2375         DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2376                 dptr_num, mask, dirtype,
2377                 (long)conn->dirptr,
2378                 dptr_TellDir(conn->dirptr)));
2379
2380         /* Initialize per TRANS2_FIND_NEXT operation data */
2381         dptr_init_search_op(conn->dirptr);
2382
2383         /* We don't need to check for VOL here as this is returned by
2384                 a different TRANS2 call. */
2385
2386         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
2387         if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2388                 dont_descend = True;
2389
2390         p = pdata;
2391         space_remaining = max_data_bytes;
2392         out_of_space = False;
2393
2394         /*
2395          * Seek to the correct position. We no longer use the resume key but
2396          * depend on the last file name instead.
2397          */
2398
2399         if(*resume_name && !continue_bit) {
2400                 SMB_STRUCT_STAT st;
2401
2402                 long current_pos = 0;
2403                 /*
2404                  * Remember, name_to_8_3 is called by
2405                  * get_lanman2_dir_entry(), so the resume name
2406                  * could be mangled. Ensure we check the unmangled name.
2407                  */
2408
2409                 if (mangle_is_mangled(resume_name, conn->params)) {
2410                         char *new_resume_name = NULL;
2411                         mangle_lookup_name_from_8_3(ctx,
2412                                                 resume_name,
2413                                                 &new_resume_name,
2414                                                 conn->params);
2415                         if (new_resume_name) {
2416                                 resume_name = new_resume_name;
2417                         }
2418                 }
2419
2420                 /*
2421                  * Fix for NT redirector problem triggered by resume key indexes
2422                  * changing between directory scans. We now return a resume key of 0
2423                  * and instead look for the filename to continue from (also given
2424                  * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2425                  * findfirst/findnext (as is usual) then the directory pointer
2426                  * should already be at the correct place.
2427                  */
2428
2429                 finished = !dptr_SearchDir(conn->dirptr, resume_name, &current_pos, &st);
2430         } /* end if resume_name && !continue_bit */
2431
2432         for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
2433                 bool got_exact_match = False;
2434
2435                 /* this is a heuristic to avoid seeking the dirptr except when 
2436                         absolutely necessary. It allows for a filename of about 40 chars */
2437                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2438                         out_of_space = True;
2439                         finished = False;
2440                 } else {
2441                         finished = !get_lanman2_dir_entry(ctx,
2442                                                 conn,
2443                                                 req->flags2,
2444                                                 mask,dirtype,info_level,
2445                                                 requires_resume_key,dont_descend,
2446                                                 ask_sharemode,
2447                                                 &p,pdata,data_end,
2448                                                 space_remaining, &out_of_space,
2449                                                 &got_exact_match,
2450                                                 &last_entry_off, ea_list);
2451                 }
2452
2453                 if (finished && out_of_space)
2454                         finished = False;
2455
2456                 if (!finished && !out_of_space)
2457                         numentries++;
2458
2459                 /*
2460                  * As an optimisation if we know we aren't looking
2461                  * for a wildcard name (ie. the name matches the wildcard exactly)
2462                  * then we can finish on any (first) match.
2463                  * This speeds up large directory searches. JRA.
2464                  */
2465
2466                 if(got_exact_match)
2467                         finished = True;
2468
2469                 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2470         }
2471
2472         DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2473                 smb_fn_name(req->cmd),
2474                 mask, directory, dirtype, numentries ) );
2475
2476         /* Check if we can close the dirptr */
2477         if(close_after_request || (finished && close_if_end)) {
2478                 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2479                 dptr_close(&dptr_num); /* This frees up the saved mask */
2480         }
2481
2482         /* Set up the return parameter block */
2483         SSVAL(params,0,numentries);
2484         SSVAL(params,2,finished);
2485         SSVAL(params,4,0); /* Never an EA error */
2486         SSVAL(params,6,last_entry_off);
2487
2488         send_trans2_replies(conn, req, params, 8, pdata, PTR_DIFF(p,pdata),
2489                             max_data_bytes);
2490
2491         return;
2492 }
2493
2494 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
2495 {
2496         E_md4hash(lp_servicename(SNUM(conn)),objid);
2497         return objid;
2498 }
2499
2500 static void samba_extended_info_version(struct smb_extended_info *extended_info)
2501 {
2502         SMB_ASSERT(extended_info != NULL);
2503
2504         extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
2505         extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
2506                                        | ((SAMBA_VERSION_MINOR & 0xff) << 16)
2507                                        | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
2508 #ifdef SAMBA_VERSION_REVISION
2509         extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
2510 #endif
2511         extended_info->samba_subversion = 0;
2512 #ifdef SAMBA_VERSION_RC_RELEASE
2513         extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
2514 #else
2515 #ifdef SAMBA_VERSION_PRE_RELEASE
2516         extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
2517 #endif
2518 #endif
2519 #ifdef SAMBA_VERSION_VENDOR_PATCH
2520         extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
2521 #endif
2522         extended_info->samba_gitcommitdate = 0;
2523 #ifdef SAMBA_VERSION_GIT_COMMIT_TIME
2524         unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_GIT_COMMIT_TIME);
2525 #endif
2526
2527         memset(extended_info->samba_version_string, 0,
2528                sizeof(extended_info->samba_version_string));
2529
2530         snprintf (extended_info->samba_version_string,
2531                   sizeof(extended_info->samba_version_string),
2532                   "%s", samba_version_string());
2533 }
2534
2535 /****************************************************************************
2536  Reply to a TRANS2_QFSINFO (query filesystem info).
2537 ****************************************************************************/
2538
2539 static void call_trans2qfsinfo(connection_struct *conn,
2540                                struct smb_request *req,
2541                                char **pparams, int total_params,
2542                                char **ppdata, int total_data,
2543                                unsigned int max_data_bytes)
2544 {
2545         char *pdata, *end_data;
2546         char *params = *pparams;
2547         uint16 info_level;
2548         int data_len, len;
2549         SMB_STRUCT_STAT st;
2550         const char *vname = volume_label(SNUM(conn));
2551         int snum = SNUM(conn);
2552         char *fstype = lp_fstype(SNUM(conn));
2553         uint32 additional_flags = 0;
2554         
2555         if (total_params < 2) {
2556                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2557                 return;
2558         }
2559
2560         info_level = SVAL(params,0);
2561
2562         if (IS_IPC(conn)) {
2563                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
2564                         DEBUG(0,("call_trans2qfsinfo: not an allowed "
2565                                 "info level (0x%x) on IPC$.\n",
2566                                 (unsigned int)info_level));
2567                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
2568                         return;
2569                 }
2570         }
2571
2572         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
2573                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
2574                         DEBUG(0,("call_trans2qfsinfo: encryption required "
2575                                 "and info level 0x%x sent.\n",
2576                                 (unsigned int)info_level));
2577                         exit_server_cleanly("encryption required "
2578                                 "on connection");
2579                         return;
2580                 }
2581         }
2582
2583         DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
2584
2585         if(SMB_VFS_STAT(conn,".",&st)!=0) {
2586                 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
2587                 reply_doserror(req, ERRSRV, ERRinvdevice);
2588                 return;
2589         }
2590
2591         *ppdata = (char *)SMB_REALLOC(
2592                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2593         if (*ppdata == NULL ) {
2594                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2595                 return;
2596         }
2597
2598         pdata = *ppdata;
2599         memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2600         end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2601
2602         switch (info_level) {
2603                 case SMB_INFO_ALLOCATION:
2604                 {
2605                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2606                         data_len = 18;
2607                         if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2608                                 reply_unixerror(req, ERRHRD, ERRgeneral);
2609                                 return;
2610                         }
2611
2612                         block_size = lp_block_size(snum);
2613                         if (bsize < block_size) {
2614                                 uint64_t factor = block_size/bsize;
2615                                 bsize = block_size;
2616                                 dsize /= factor;
2617                                 dfree /= factor;
2618                         }
2619                         if (bsize > block_size) {
2620                                 uint64_t factor = bsize/block_size;
2621                                 bsize = block_size;
2622                                 dsize *= factor;
2623                                 dfree *= factor;
2624                         }
2625                         bytes_per_sector = 512;
2626                         sectors_per_unit = bsize/bytes_per_sector;
2627
2628                         DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2629 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2630                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2631
2632                         SIVAL(pdata,l1_idFileSystem,st.st_dev);
2633                         SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2634                         SIVAL(pdata,l1_cUnit,dsize);
2635                         SIVAL(pdata,l1_cUnitAvail,dfree);
2636                         SSVAL(pdata,l1_cbSector,bytes_per_sector);
2637                         break;
2638                 }
2639
2640                 case SMB_INFO_VOLUME:
2641                         /* Return volume name */
2642                         /* 
2643                          * Add volume serial number - hash of a combination of
2644                          * the called hostname and the service name.
2645                          */
2646                         SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2647                         /*
2648                          * Win2k3 and previous mess this up by sending a name length
2649                          * one byte short. I believe only older clients (OS/2 Win9x) use
2650                          * this call so try fixing this by adding a terminating null to
2651                          * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2652                          */
2653                         len = srvstr_push(
2654                                 pdata, req->flags2,
2655                                 pdata+l2_vol_szVolLabel, vname,
2656                                 PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
2657                                 STR_NOALIGN|STR_TERMINATE);
2658                         SCVAL(pdata,l2_vol_cch,len);
2659                         data_len = l2_vol_szVolLabel + len;
2660                         DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
2661                                 (unsigned)st.st_ctime, len, vname));
2662                         break;
2663
2664                 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2665                 case SMB_FS_ATTRIBUTE_INFORMATION:
2666
2667                         additional_flags = 0;
2668 #if defined(HAVE_SYS_QUOTAS)
2669                         additional_flags |= FILE_VOLUME_QUOTAS;
2670 #endif
2671
2672                         if(lp_nt_acl_support(SNUM(conn))) {
2673                                 additional_flags |= FILE_PERSISTENT_ACLS;
2674                         }
2675
2676                         /* Capabilities are filled in at connection time through STATVFS call */
2677                         additional_flags |= conn->fs_capabilities;
2678
2679                         SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2680                                 FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
2681                                 additional_flags); /* FS ATTRIBUTES */
2682
2683                         SIVAL(pdata,4,255); /* Max filename component length */
2684                         /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2685                                 and will think we can't do long filenames */
2686                         len = srvstr_push(pdata, req->flags2, pdata+12, fstype,
2687                                           PTR_DIFF(end_data, pdata+12),
2688                                           STR_UNICODE);
2689                         SIVAL(pdata,8,len);
2690                         data_len = 12 + len;
2691                         break;
2692
2693                 case SMB_QUERY_FS_LABEL_INFO:
2694                 case SMB_FS_LABEL_INFORMATION:
2695                         len = srvstr_push(pdata, req->flags2, pdata+4, vname,
2696                                           PTR_DIFF(end_data, pdata+4), 0);
2697                         data_len = 4 + len;
2698                         SIVAL(pdata,0,len);
2699                         break;
2700
2701                 case SMB_QUERY_FS_VOLUME_INFO:      
2702                 case SMB_FS_VOLUME_INFORMATION:
2703
2704                         /* 
2705                          * Add volume serial number - hash of a combination of
2706                          * the called hostname and the service name.
2707                          */
2708                         SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ 
2709                                 (str_checksum(get_local_machine_name())<<16));
2710
2711                         /* Max label len is 32 characters. */
2712                         len = srvstr_push(pdata, req->flags2, pdata+18, vname,
2713                                           PTR_DIFF(end_data, pdata+18),
2714                                           STR_UNICODE);
2715                         SIVAL(pdata,12,len);
2716                         data_len = 18+len;
2717
2718                         DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", 
2719                                 (int)strlen(vname),vname, lp_servicename(snum)));
2720                         break;
2721
2722                 case SMB_QUERY_FS_SIZE_INFO:
2723                 case SMB_FS_SIZE_INFORMATION:
2724                 {
2725                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2726                         data_len = 24;
2727                         if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2728                                 reply_unixerror(req, ERRHRD, ERRgeneral);
2729                                 return;
2730                         }
2731                         block_size = lp_block_size(snum);
2732                         if (bsize < block_size) {
2733                                 uint64_t factor = block_size/bsize;
2734                                 bsize = block_size;
2735                                 dsize /= factor;
2736                                 dfree /= factor;
2737                         }
2738                         if (bsize > block_size) {
2739                                 uint64_t factor = bsize/block_size;
2740                                 bsize = block_size;
2741                                 dsize *= factor;
2742                                 dfree *= factor;
2743                         }
2744                         bytes_per_sector = 512;
2745                         sectors_per_unit = bsize/bytes_per_sector;
2746                         DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2747 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2748                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2749                         SBIG_UINT(pdata,0,dsize);
2750                         SBIG_UINT(pdata,8,dfree);
2751                         SIVAL(pdata,16,sectors_per_unit);
2752                         SIVAL(pdata,20,bytes_per_sector);
2753                         break;
2754                 }
2755
2756                 case SMB_FS_FULL_SIZE_INFORMATION:
2757                 {
2758                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2759                         data_len = 32;
2760                         if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
2761                                 reply_unixerror(req, ERRHRD, ERRgeneral);
2762                                 return;
2763                         }
2764                         block_size = lp_block_size(snum);
2765                         if (bsize < block_size) {
2766                                 uint64_t factor = block_size/bsize;
2767                                 bsize = block_size;
2768                                 dsize /= factor;
2769                                 dfree /= factor;
2770                         }
2771                         if (bsize > block_size) {
2772                                 uint64_t factor = bsize/block_size;
2773                                 bsize = block_size;
2774                                 dsize *= factor;
2775                                 dfree *= factor;
2776                         }
2777                         bytes_per_sector = 512;
2778                         sectors_per_unit = bsize/bytes_per_sector;
2779                         DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2780 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2781                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2782                         SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2783                         SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2784                         SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2785                         SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2786                         SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2787                         break;
2788                 }
2789
2790                 case SMB_QUERY_FS_DEVICE_INFO:
2791                 case SMB_FS_DEVICE_INFORMATION:
2792                         data_len = 8;
2793                         SIVAL(pdata,0,0); /* dev type */
2794                         SIVAL(pdata,4,0); /* characteristics */
2795                         break;
2796
2797 #ifdef HAVE_SYS_QUOTAS
2798                 case SMB_FS_QUOTA_INFORMATION:
2799                 /* 
2800                  * what we have to send --metze:
2801                  *
2802                  * Unknown1:            24 NULL bytes
2803                  * Soft Quota Treshold: 8 bytes seems like uint64_t or so
2804                  * Hard Quota Limit:    8 bytes seems like uint64_t or so
2805                  * Quota Flags:         2 byte :
2806                  * Unknown3:            6 NULL bytes
2807                  *
2808                  * 48 bytes total
2809                  * 
2810                  * details for Quota Flags:
2811                  * 
2812                  * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2813                  * 0x0010 Log Warn:  log if the user exceeds his Soft Quota
2814                  * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2815                  * 0x0001 Enable Quotas: enable quota for this fs
2816                  *
2817                  */
2818                 {
2819                         /* we need to fake up a fsp here,
2820                          * because its not send in this call
2821                          */
2822                         files_struct fsp;
2823                         SMB_NTQUOTA_STRUCT quotas;
2824                         
2825                         ZERO_STRUCT(fsp);
2826                         ZERO_STRUCT(quotas);
2827                         
2828                         fsp.conn = conn;
2829                         fsp.fnum = -1;
2830                         
2831                         /* access check */
2832                         if (conn->server_info->utok.uid != 0) {
2833                                 DEBUG(0,("set_user_quota: access_denied "
2834                                          "service [%s] user [%s]\n",
2835                                          lp_servicename(SNUM(conn)),
2836                                          conn->server_info->unix_name));
2837                                 reply_doserror(req, ERRDOS, ERRnoaccess);
2838                                 return;
2839                         }
2840                         
2841                         if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
2842                                 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2843                                 reply_doserror(req, ERRSRV, ERRerror);
2844                                 return;
2845                         }
2846
2847                         data_len = 48;
2848
2849                         DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));          
2850                 
2851                         /* Unknown1 24 NULL bytes*/
2852                         SBIG_UINT(pdata,0,(uint64_t)0);
2853                         SBIG_UINT(pdata,8,(uint64_t)0);
2854                         SBIG_UINT(pdata,16,(uint64_t)0);
2855                 
2856                         /* Default Soft Quota 8 bytes */
2857                         SBIG_UINT(pdata,24,quotas.softlim);
2858
2859                         /* Default Hard Quota 8 bytes */
2860                         SBIG_UINT(pdata,32,quotas.hardlim);
2861         
2862                         /* Quota flag 2 bytes */
2863                         SSVAL(pdata,40,quotas.qflags);
2864                 
2865                         /* Unknown3 6 NULL bytes */
2866                         SSVAL(pdata,42,0);
2867                         SIVAL(pdata,44,0);
2868                         
2869                         break;
2870                 }
2871 #endif /* HAVE_SYS_QUOTAS */
2872                 case SMB_FS_OBJECTID_INFORMATION:
2873                 {
2874                         unsigned char objid[16];
2875                         struct smb_extended_info extended_info;
2876                         memcpy(pdata,create_volume_objectid(conn, objid),16);
2877                         samba_extended_info_version (&extended_info);
2878                         SIVAL(pdata,16,extended_info.samba_magic);
2879                         SIVAL(pdata,20,extended_info.samba_version);
2880                         SIVAL(pdata,24,extended_info.samba_subversion);
2881                         SBIG_UINT(pdata,28,extended_info.samba_gitcommitdate);
2882                         memcpy(pdata+36,extended_info.samba_version_string,28);
2883                         data_len = 64;
2884                         break;
2885                 }
2886
2887                 /*
2888                  * Query the version and capabilities of the CIFS UNIX extensions
2889                  * in use.
2890                  */
2891
2892                 case SMB_QUERY_CIFS_UNIX_INFO:
2893                 {
2894                         bool large_write = lp_min_receive_file_size() &&
2895                                                 !srv_is_signing_active();
2896                         bool large_read = !srv_is_signing_active();
2897                         int encrypt_caps = 0;
2898
2899                         if (!lp_unix_extensions()) {
2900                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2901                                 return;
2902                         }
2903
2904                         switch (conn->encrypt_level) {
2905                         case 0:
2906                                 encrypt_caps = 0;
2907                                 break;
2908                         case 1:
2909                         case Auto:
2910                                 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP;
2911                                 break;
2912                         case Required:
2913                                 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP|
2914                                                 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP;
2915                                 large_write = false;
2916                                 large_read = false;
2917                                 break;
2918                         }
2919
2920                         data_len = 12;
2921                         SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2922                         SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2923
2924                         /* We have POSIX ACLs, pathname, encryption, 
2925                          * large read/write, and locking capability. */
2926
2927                         SBIG_UINT(pdata,4,((uint64_t)(
2928                                         CIFS_UNIX_POSIX_ACLS_CAP|
2929                                         CIFS_UNIX_POSIX_PATHNAMES_CAP|
2930                                         CIFS_UNIX_FCNTL_LOCKS_CAP|
2931                                         CIFS_UNIX_EXTATTR_CAP|
2932                                         CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP|
2933                                         encrypt_caps|
2934                                         (large_read ? CIFS_UNIX_LARGE_READ_CAP : 0) |
2935                                         (large_write ?
2936                                         CIFS_UNIX_LARGE_WRITE_CAP : 0))));
2937                         break;
2938                 }
2939
2940                 case SMB_QUERY_POSIX_FS_INFO:
2941                 {
2942                         int rc;
2943                         vfs_statvfs_struct svfs;
2944
2945                         if (!lp_unix_extensions()) {
2946                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2947                                 return;
2948                         }
2949
2950                         rc = SMB_VFS_STATVFS(conn, ".", &svfs);
2951
2952                         if (!rc) {
2953                                 data_len = 56;
2954                                 SIVAL(pdata,0,svfs.OptimalTransferSize);
2955                                 SIVAL(pdata,4,svfs.BlockSize);
2956                                 SBIG_UINT(pdata,8,svfs.TotalBlocks);
2957                                 SBIG_UINT(pdata,16,svfs.BlocksAvail);
2958                                 SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
2959                                 SBIG_UINT(pdata,32,svfs.TotalFileNodes);
2960                                 SBIG_UINT(pdata,40,svfs.FreeFileNodes);
2961                                 SBIG_UINT(pdata,48,svfs.FsIdentifier);
2962                                 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
2963 #ifdef EOPNOTSUPP
2964                         } else if (rc == EOPNOTSUPP) {
2965                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2966                                 return;
2967 #endif /* EOPNOTSUPP */
2968                         } else {
2969                                 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2970                                 reply_doserror(req, ERRSRV, ERRerror);
2971                                 return;
2972                         }
2973                         break;
2974                 }
2975
2976                 case SMB_QUERY_POSIX_WHOAMI:
2977                 {
2978                         uint32_t flags = 0;
2979                         uint32_t sid_bytes;
2980                         int i;
2981
2982                         if (!lp_unix_extensions()) {
2983                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2984                                 return;
2985                         }
2986
2987                         if (max_data_bytes < 40) {
2988                                 reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2989                                 return;
2990                         }
2991
2992                         /* We ARE guest if global_sid_Builtin_Guests is
2993                          * in our list of SIDs.
2994                          */
2995                         if (nt_token_check_sid(&global_sid_Builtin_Guests,
2996                                                conn->server_info->ptok)) {
2997                                 flags |= SMB_WHOAMI_GUEST;
2998                         }
2999
3000                         /* We are NOT guest if global_sid_Authenticated_Users
3001                          * is in our list of SIDs.
3002                          */
3003                         if (nt_token_check_sid(&global_sid_Authenticated_Users,
3004                                                conn->server_info->ptok)) {
3005                                 flags &= ~SMB_WHOAMI_GUEST;
3006                         }
3007
3008                         /* NOTE: 8 bytes for UID/GID, irrespective of native
3009                          * platform size. This matches
3010                          * SMB_QUERY_FILE_UNIX_BASIC and friends.
3011                          */
3012                         data_len = 4 /* flags */
3013                             + 4 /* flag mask */
3014                             + 8 /* uid */
3015                             + 8 /* gid */
3016                             + 4 /* ngroups */
3017                             + 4 /* num_sids */
3018                             + 4 /* SID bytes */
3019                             + 4 /* pad/reserved */
3020                             + (conn->server_info->utok.ngroups * 8)
3021                                 /* groups list */
3022                             + (conn->server_info->ptok->num_sids *
3023                                     SID_MAX_SIZE)
3024                                 /* SID list */;
3025
3026                         SIVAL(pdata, 0, flags);
3027                         SIVAL(pdata, 4, SMB_WHOAMI_MASK);
3028                         SBIG_UINT(pdata, 8,
3029                                   (uint64_t)conn->server_info->utok.uid);
3030                         SBIG_UINT(pdata, 16,
3031                                   (uint64_t)conn->server_info->utok.gid);
3032
3033
3034                         if (data_len >= max_data_bytes) {
3035                                 /* Potential overflow, skip the GIDs and SIDs. */
3036
3037                                 SIVAL(pdata, 24, 0); /* num_groups */
3038                                 SIVAL(pdata, 28, 0); /* num_sids */
3039                                 SIVAL(pdata, 32, 0); /* num_sid_bytes */
3040                                 SIVAL(pdata, 36, 0); /* reserved */
3041
3042                                 data_len = 40;
3043                                 break;
3044                         }
3045
3046                         SIVAL(pdata, 24, conn->server_info->utok.ngroups);
3047                         SIVAL(pdata, 28, conn->server_info->num_sids);
3048
3049                         /* We walk the SID list twice, but this call is fairly
3050                          * infrequent, and I don't expect that it's performance
3051                          * sensitive -- jpeach
3052                          */
3053                         for (i = 0, sid_bytes = 0;
3054                              i < conn->server_info->ptok->num_sids; ++i) {
3055                                 sid_bytes += ndr_size_dom_sid(
3056                                         &conn->server_info->ptok->user_sids[i],
3057                                         NULL, 
3058                                         0);
3059                         }
3060
3061                         /* SID list byte count */
3062                         SIVAL(pdata, 32, sid_bytes);
3063
3064                         /* 4 bytes pad/reserved - must be zero */
3065                         SIVAL(pdata, 36, 0);
3066                         data_len = 40;
3067
3068                         /* GID list */
3069                         for (i = 0; i < conn->server_info->utok.ngroups; ++i) {
3070                                 SBIG_UINT(pdata, data_len,
3071                                           (uint64_t)conn->server_info->utok.groups[i]);
3072                                 data_len += 8;
3073                         }
3074
3075                         /* SID list */
3076                         for (i = 0;
3077                             i < conn->server_info->ptok->num_sids; ++i) {
3078                                 int sid_len = ndr_size_dom_sid(
3079                                         &conn->server_info->ptok->user_sids[i],
3080                                         NULL,
3081                                         0);
3082
3083                                 sid_linearize(pdata + data_len, sid_len,
3084                                     &conn->server_info->ptok->user_sids[i]);
3085                                 data_len += sid_len;
3086                         }
3087
3088                         break;
3089                 }
3090
3091                 case SMB_MAC_QUERY_FS_INFO:
3092                         /*
3093                          * Thursby MAC extension... ONLY on NTFS filesystems
3094                          * once we do streams then we don't need this
3095                          */
3096                         if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
3097                                 data_len = 88;
3098                                 SIVAL(pdata,84,0x100); /* Don't support mac... */
3099                                 break;
3100                         }
3101                         /* drop through */
3102                 default:
3103                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3104                         return;
3105         }
3106
3107
3108         send_trans2_replies(conn, req, params, 0, pdata, data_len,
3109                             max_data_bytes);
3110
3111         DEBUG( 4, ( "%s info_level = %d\n",
3112                     smb_fn_name(req->cmd), info_level) );
3113
3114         return;
3115 }
3116
3117 /****************************************************************************
3118  Reply to a TRANS2_SETFSINFO (set filesystem info).
3119 ****************************************************************************/
3120
3121 static void call_trans2setfsinfo(connection_struct *conn,
3122                                  struct smb_request *req,
3123                                  char **pparams, int total_params,
3124                                  char **ppdata, int total_data,
3125                                  unsigned int max_data_bytes)
3126 {
3127         char *pdata = *ppdata;
3128         char *params = *pparams;
3129         uint16 info_level;
3130
3131         DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn))));
3132
3133         /*  */
3134         if (total_params < 4) {
3135                 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
3136                         total_params));
3137                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3138                 return;
3139         }
3140
3141         info_level = SVAL(params,2);
3142
3143         if (IS_IPC(conn)) {
3144                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION &&
3145                                 info_level != SMB_SET_CIFS_UNIX_INFO) {
3146                         DEBUG(0,("call_trans2setfsinfo: not an allowed "
3147                                 "info level (0x%x) on IPC$.\n",
3148                                 (unsigned int)info_level));
3149                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
3150                         return;
3151                 }
3152         }
3153
3154         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
3155                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
3156                         DEBUG(0,("call_trans2setfsinfo: encryption required "
3157                                 "and info level 0x%x sent.\n",
3158                                 (unsigned int)info_level));
3159                         exit_server_cleanly("encryption required "
3160                                 "on connection");
3161                         return;
3162                 }
3163         }
3164
3165         switch(info_level) {
3166                 case SMB_SET_CIFS_UNIX_INFO:
3167                         {
3168                                 uint16 client_unix_major;
3169                                 uint16 client_unix_minor;
3170                                 uint32 client_unix_cap_low;
3171                                 uint32 client_unix_cap_high;
3172
3173                                 if (!lp_unix_extensions()) {
3174                                         reply_nterror(req,
3175                                                       NT_STATUS_INVALID_LEVEL);
3176                                         return;
3177                                 }
3178
3179                                 /* There should be 12 bytes of capabilities set. */
3180                                 if (total_data < 8) {
3181                                         reply_nterror(
3182                                                 req,
3183                                                 NT_STATUS_INVALID_PARAMETER);
3184                                         return;
3185                                 }
3186                                 client_unix_major = SVAL(pdata,0);
3187                                 client_unix_minor = SVAL(pdata,2);
3188                                 client_unix_cap_low = IVAL(pdata,4);
3189                                 client_unix_cap_high = IVAL(pdata,8);
3190                                 /* Just print these values for now. */
3191                                 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
3192 cap_low = 0x%x, cap_high = 0x%x\n",
3193                                         (unsigned int)client_unix_major,
3194                                         (unsigned int)client_unix_minor,
3195                                         (unsigned int)client_unix_cap_low,
3196                                         (unsigned int)client_unix_cap_high ));
3197
3198                                 /* Here is where we must switch to posix pathname processing... */
3199                                 if (client_unix_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
3200                                         lp_set_posix_pathnames();
3201                                         mangle_change_to_posix();
3202                                 }
3203
3204                                 if ((client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
3205                                     !(client_unix_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
3206                                         /* Client that knows how to do posix locks,
3207                                          * but not posix open/mkdir operations. Set a
3208                                          * default type for read/write checks. */
3209
3210                                         lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
3211
3212                                 }
3213                                 break;
3214                         }
3215
3216                 case SMB_REQUEST_TRANSPORT_ENCRYPTION:
3217                         {
3218                                 NTSTATUS status;
3219                                 size_t param_len = 0;
3220                                 size_t data_len = total_data;
3221
3222                                 if (!lp_unix_extensions()) {
3223                                         reply_nterror(
3224                                                 req,
3225                                                 NT_STATUS_INVALID_LEVEL);
3226                                         return;
3227                                 }
3228
3229                                 if (lp_smb_encrypt(SNUM(conn)) == false) {
3230                                         reply_nterror(
3231                                                 req,
3232                                                 NT_STATUS_NOT_SUPPORTED);
3233                                         return;
3234                                 }
3235
3236                                 DEBUG( 4,("call_trans2setfsinfo: "
3237                                         "request transport encryption.\n"));
3238
3239                                 status = srv_request_encryption_setup(conn,
3240                                                                 (unsigned char **)ppdata,
3241                                                                 &data_len,
3242                                                                 (unsigned char **)pparams,
3243                                                                 &param_len);
3244
3245                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
3246                                                 !NT_STATUS_IS_OK(status)) {
3247                                         reply_nterror(req, status);
3248                                         return;
3249                                 }
3250
3251                                 send_trans2_replies(conn, req,
3252                                                 *pparams,
3253                                                 param_len,
3254                                                 *ppdata,
3255                                                 data_len,
3256                                                 max_data_bytes);
3257
3258                                 if (NT_STATUS_IS_OK(status)) {
3259                                         /* Server-side transport
3260                                          * encryption is now *on*. */
3261                                         status = srv_encryption_start(conn);
3262                                         if (!NT_STATUS_IS_OK(status)) {
3263                                                 exit_server_cleanly(
3264                                                         "Failure in setting "
3265                                                         "up encrypted transport");
3266                                         }
3267                                 }
3268                                 return;
3269                         }
3270
3271                 case SMB_FS_QUOTA_INFORMATION:
3272                         {
3273                                 files_struct *fsp = NULL;
3274                                 SMB_NTQUOTA_STRUCT quotas;
3275         
3276                                 ZERO_STRUCT(quotas);
3277
3278                                 /* access check */
3279                                 if ((conn->server_info->utok.uid != 0)
3280                                     ||!CAN_WRITE(conn)) {
3281                                         DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
3282                                                  lp_servicename(SNUM(conn)),
3283                                                  conn->server_info->unix_name));
3284                                         reply_doserror(req, ERRSRV, ERRaccess);
3285                                         return;
3286                                 }
3287
3288                                 /* note: normaly there're 48 bytes,
3289                                  * but we didn't use the last 6 bytes for now 
3290                                  * --metze 
3291                                  */
3292                                 fsp = file_fsp(req, SVAL(params,0));
3293
3294                                 if (!check_fsp_ntquota_handle(conn, req,
3295                                                               fsp)) {
3296                                         DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
3297                                         reply_nterror(
3298                                                 req, NT_STATUS_INVALID_HANDLE);
3299                                         return;
3300                                 }
3301
3302                                 if (total_data < 42) {
3303                                         DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
3304                                                 total_data));
3305   &nbs