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