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