r20228: Bring the calling conventions of inherit_access_acl and change_owner_to_parent
[sfrench/samba-autobuild/.git] / source / smbd / trans2.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB transaction2 handling
4    Copyright (C) Jeremy Allison                 1994-2003
5    Copyright (C) Stefan (metze) Metzmacher      2003
6    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(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("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("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         TALLOC_CTX *ctx = NULL;
757         struct ea_list *ea_list = NULL;
758         uint16 flags = 0;
759         NTSTATUS status;
760         uint32 access_mask;
761         uint32 share_mode;
762         uint32 create_disposition;
763         uint32 create_options = 0;
764
765         /*
766          * Ensure we have enough parameters to perform the operation.
767          */
768
769         if (total_params < 29) {
770                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
771         }
772
773         flags = SVAL(params, 0);
774         deny_mode = SVAL(params, 2);
775         open_attr = SVAL(params,6);
776         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
777         if (oplock_request) {
778                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
779         }
780
781 #if 0
782         return_additional_info = BITSETW(params,0);
783         open_sattr = SVAL(params, 4);
784         open_time = make_unix_date3(params+8);
785 #endif
786         open_ofun = SVAL(params,12);
787         open_size = IVAL(params,14);
788         pname = &params[28];
789
790         if (IS_IPC(conn)) {
791                 return(ERROR_DOS(ERRSRV,ERRaccess));
792         }
793
794         srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status);
795         if (!NT_STATUS_IS_OK(status)) {
796                 return ERROR_NT(status);
797         }
798
799         DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
800                 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
801                 (unsigned int)open_ofun, open_size));
802
803         /* XXXX we need to handle passed times, sattr and flags */
804
805         unix_convert(fname,conn,0,&bad_path,&sbuf);
806         if (bad_path) {
807                 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
808         }
809     
810         if (!check_name(fname,conn)) {
811                 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
812         }
813
814         if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun,
815                                 &access_mask,
816                                 &share_mode,
817                                 &create_disposition,
818                                 &create_options)) {
819                 return ERROR_DOS(ERRDOS, ERRbadaccess);
820         }
821
822         /* Any data in this call is an EA list. */
823         if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
824                 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
825         }
826
827         if (total_data != 4) {
828                 if (total_data < 10) {
829                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
830                 }
831
832                 if (IVAL(pdata,0) > total_data) {
833                         DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
834                                 IVAL(pdata,0), (unsigned int)total_data));
835                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
836                 }
837
838                 ctx = talloc_init("TRANS2_OPEN_SET_EA");
839                 if (!ctx) {
840                         return ERROR_NT(NT_STATUS_NO_MEMORY);
841                 }
842                 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
843                 if (!ea_list) {
844                         talloc_destroy(ctx);
845                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
846                 }
847         } else if (IVAL(pdata,0) != 4) {
848                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
849         }
850
851         status = open_file_ntcreate(conn,fname,&sbuf,
852                 access_mask,
853                 share_mode,
854                 create_disposition,
855                 create_options,
856                 open_attr,
857                 oplock_request,
858                 &smb_action, &fsp);
859       
860         if (!NT_STATUS_IS_OK(status)) {
861                 talloc_destroy(ctx);
862                 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
863                         /* We have re-scheduled this call. */
864                         return -1;
865                 }
866                 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
867         }
868
869         size = get_file_size(sbuf);
870         fattr = dos_mode(conn,fname,&sbuf);
871         mtime = sbuf.st_mtime;
872         inode = sbuf.st_ino;
873         if (fattr & aDIR) {
874                 talloc_destroy(ctx);
875                 close_file(fsp,ERROR_CLOSE);
876                 return(ERROR_DOS(ERRDOS,ERRnoaccess));
877         }
878
879         /* Save the requested allocation size. */
880         /* Allocate space for the file if a size hint is supplied */
881         if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) {
882                 SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)open_size;
883                 if (allocation_size && (allocation_size > (SMB_BIG_UINT)size)) {
884                         fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
885                         if (fsp->is_directory) {
886                                 close_file(fsp,ERROR_CLOSE);
887                                 /* Can't set allocation size on a directory. */
888                                 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
889                         }
890                         if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
891                                 close_file(fsp,ERROR_CLOSE);
892                                 return ERROR_NT(NT_STATUS_DISK_FULL);
893                         }
894
895                         /* Adjust size here to return the right size in the reply.
896                            Windows does it this way. */
897                         size = fsp->initial_allocation_size;
898                 } else {
899                         fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)size);
900                 }
901         }
902
903         if (total_data && smb_action == FILE_WAS_CREATED) {
904                 status = set_ea(conn, fsp, fname, ea_list);
905                 talloc_destroy(ctx);
906                 if (!NT_STATUS_IS_OK(status)) {
907                         close_file(fsp,ERROR_CLOSE);
908                         return ERROR_NT(status);
909                 }
910         }
911
912         /* Realloc the size of parameters and data we will return */
913         *pparams = (char *)SMB_REALLOC(*pparams, 30);
914         if(*pparams == NULL ) {
915                 return ERROR_NT(NT_STATUS_NO_MEMORY);
916         }
917         params = *pparams;
918
919         SSVAL(params,0,fsp->fnum);
920         SSVAL(params,2,open_attr);
921         srv_put_dos_date2(params,4, mtime);
922         SIVAL(params,8, (uint32)size);
923         SSVAL(params,12,deny_mode);
924         SSVAL(params,14,0); /* open_type - file or directory. */
925         SSVAL(params,16,0); /* open_state - only valid for IPC device. */
926
927         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
928                 smb_action |= EXTENDED_OPLOCK_GRANTED;
929         }
930
931         SSVAL(params,18,smb_action);
932
933         /*
934          * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
935          */
936         SIVAL(params,20,inode);
937         SSVAL(params,24,0); /* Padding. */
938         if (flags & 8) {
939                 uint32 ea_size = estimate_ea_size(conn, fsp, fname);
940                 SIVAL(params, 26, ea_size);
941         } else {
942                 SIVAL(params, 26, 0);
943         }
944
945         /* Send the required number of replies */
946         send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0, max_data_bytes);
947
948         return -1;
949 }
950
951 /*********************************************************
952  Routine to check if a given string matches exactly.
953  as a special case a mask of "." does NOT match. That
954  is required for correct wildcard semantics
955  Case can be significant or not.
956 **********************************************************/
957
958 static BOOL exact_match(connection_struct *conn, char *str, char *mask)
959 {
960         if (mask[0] == '.' && mask[1] == 0)
961                 return False;
962         if (conn->case_sensitive)
963                 return strcmp(str,mask)==0;
964         if (StrCaseCmp(str,mask) != 0) {
965                 return False;
966         }
967         if (dptr_has_wild(conn->dirptr)) {
968                 return False;
969         }
970         return True;
971 }
972
973 /****************************************************************************
974  Return the filetype for UNIX extensions.
975 ****************************************************************************/
976
977 static uint32 unix_filetype(mode_t mode)
978 {
979         if(S_ISREG(mode))
980                 return UNIX_TYPE_FILE;
981         else if(S_ISDIR(mode))
982                 return UNIX_TYPE_DIR;
983 #ifdef S_ISLNK
984         else if(S_ISLNK(mode))
985                 return UNIX_TYPE_SYMLINK;
986 #endif
987 #ifdef S_ISCHR
988         else if(S_ISCHR(mode))
989                 return UNIX_TYPE_CHARDEV;
990 #endif
991 #ifdef S_ISBLK
992         else if(S_ISBLK(mode))
993                 return UNIX_TYPE_BLKDEV;
994 #endif
995 #ifdef S_ISFIFO
996         else if(S_ISFIFO(mode))
997                 return UNIX_TYPE_FIFO;
998 #endif
999 #ifdef S_ISSOCK
1000         else if(S_ISSOCK(mode))
1001                 return UNIX_TYPE_SOCKET;
1002 #endif
1003
1004         DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
1005         return UNIX_TYPE_UNKNOWN;
1006 }
1007
1008 /****************************************************************************
1009  Map wire perms onto standard UNIX permissions. Obey share restrictions.
1010 ****************************************************************************/
1011
1012 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
1013 {
1014         mode_t ret = 0;
1015
1016         if (perms == SMB_MODE_NO_CHANGE)
1017                 return pst->st_mode;
1018
1019         ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
1020         ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
1021         ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
1022         ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
1023         ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
1024         ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
1025         ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
1026         ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
1027         ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
1028 #ifdef S_ISVTX
1029         ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
1030 #endif
1031 #ifdef S_ISGID
1032         ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
1033 #endif
1034 #ifdef S_ISUID
1035         ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
1036 #endif
1037
1038         if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
1039                 ret &= lp_dir_mask(SNUM(conn));
1040                 /* Add in force bits */
1041                 ret |= lp_force_dir_mode(SNUM(conn));
1042         } else {
1043                 /* Apply mode mask */
1044                 ret &= lp_create_mask(SNUM(conn));
1045                 /* Add in force bits */
1046                 ret |= lp_force_create_mode(SNUM(conn));
1047         }
1048
1049         return ret;
1050 }
1051
1052 /****************************************************************************
1053  Get a level dependent lanman2 dir entry.
1054 ****************************************************************************/
1055
1056 static BOOL get_lanman2_dir_entry(connection_struct *conn,
1057                                   void *inbuf, char *outbuf,
1058                                  char *path_mask,uint32 dirtype,int info_level,
1059                                  int requires_resume_key,
1060                                  BOOL dont_descend,char **ppdata, 
1061                                  char *base_data, int space_remaining, 
1062                                  BOOL *out_of_space, BOOL *got_exact_match,
1063                                  int *last_entry_off, struct ea_list *name_list, TALLOC_CTX *ea_ctx)
1064 {
1065         const char *dname;
1066         BOOL found = False;
1067         SMB_STRUCT_STAT sbuf;
1068         pstring mask;
1069         pstring pathreal;
1070         pstring fname;
1071         char *p, *q, *pdata = *ppdata;
1072         uint32 reskey=0;
1073         long prev_dirpos=0;
1074         uint32 mode=0;
1075         SMB_OFF_T file_size = 0;
1076         SMB_BIG_UINT allocation_size = 0;
1077         uint32 len;
1078         struct timespec mdate_ts, adate_ts, create_date_ts;
1079         time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1080         char *nameptr;
1081         char *last_entry_ptr;
1082         BOOL was_8_3;
1083         uint32 nt_extmode; /* Used for NT connections instead of mode */
1084         BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
1085         BOOL check_mangled_names = lp_manglednames(conn->params);
1086
1087         *fname = 0;
1088         *out_of_space = False;
1089         *got_exact_match = False;
1090
1091         ZERO_STRUCT(mdate_ts);
1092         ZERO_STRUCT(adate_ts);
1093         ZERO_STRUCT(create_date_ts);
1094
1095         if (!conn->dirptr)
1096                 return(False);
1097
1098         p = strrchr_m(path_mask,'/');
1099         if(p != NULL) {
1100                 if(p[1] == '\0')
1101                         pstrcpy(mask,"*.*");
1102                 else
1103                         pstrcpy(mask, p+1);
1104         } else
1105                 pstrcpy(mask, path_mask);
1106
1107
1108         while (!found) {
1109                 BOOL got_match;
1110                 BOOL ms_dfs_link = False;
1111
1112                 /* Needed if we run out of space */
1113                 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
1114                 dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf);
1115
1116                 /*
1117                  * Due to bugs in NT client redirectors we are not using
1118                  * resume keys any more - set them to zero.
1119                  * Check out the related comments in findfirst/findnext.
1120                  * JRA.
1121                  */
1122
1123                 reskey = 0;
1124
1125                 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
1126                         (long)conn->dirptr,curr_dirpos));
1127       
1128                 if (!dname) 
1129                         return(False);
1130
1131                 pstrcpy(fname,dname);      
1132
1133                 if(!(got_match = *got_exact_match = exact_match(conn, fname, mask)))
1134                         got_match = mask_match(fname, mask, conn->case_sensitive);
1135
1136                 if(!got_match && check_mangled_names &&
1137                    !mangle_is_8_3(fname, False, conn->params)) {
1138
1139                         /*
1140                          * It turns out that NT matches wildcards against
1141                          * both long *and* short names. This may explain some
1142                          * of the wildcard wierdness from old DOS clients
1143                          * that some people have been seeing.... JRA.
1144                          */
1145
1146                         pstring newname;
1147                         pstrcpy( newname, fname);
1148                         mangle_map( newname, True, False, conn->params);
1149                         if(!(got_match = *got_exact_match = exact_match(conn, newname, mask)))
1150                                 got_match = mask_match(newname, mask, conn->case_sensitive);
1151                 }
1152
1153                 if(got_match) {
1154                         BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
1155                         if (dont_descend && !isdots)
1156                                 continue;
1157           
1158                         pstrcpy(pathreal,conn->dirpath);
1159                         if(needslash)
1160                                 pstrcat(pathreal,"/");
1161                         pstrcat(pathreal,dname);
1162
1163                         if (INFO_LEVEL_IS_UNIX(info_level)) {
1164                                 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
1165                                         DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
1166                                                 pathreal,strerror(errno)));
1167                                         continue;
1168                                 }
1169                         } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
1170
1171                                 /* Needed to show the msdfs symlinks as 
1172                                  * directories */
1173
1174                                 if(lp_host_msdfs() && 
1175                                    lp_msdfs_root(SNUM(conn)) &&
1176                                    ((ms_dfs_link = is_msdfs_link(NULL,conn, pathreal, NULL, NULL, &sbuf)) == True)) {
1177
1178                                         DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
1179                                         sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
1180
1181                                 } else {
1182
1183                                         DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
1184                                                 pathreal,strerror(errno)));
1185                                         continue;
1186                                 }
1187                         }
1188
1189                         if (ms_dfs_link) {
1190                                 mode = dos_mode_msdfs(conn,pathreal,&sbuf);
1191                         } else {
1192                                 mode = dos_mode(conn,pathreal,&sbuf);
1193                         }
1194
1195                         if (!dir_check_ftype(conn,mode,dirtype)) {
1196                                 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
1197                                 continue;
1198                         }
1199
1200                         if (!(mode & aDIR))
1201                                 file_size = get_file_size(sbuf);
1202                         allocation_size = get_allocation_size(conn,NULL,&sbuf);
1203
1204                         mdate_ts = get_mtimespec(&sbuf);
1205                         adate_ts = get_atimespec(&sbuf);
1206                         create_date_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1207
1208                         if (lp_dos_filetime_resolution(SNUM(conn))) {
1209                                 dos_filetime_timespec(&create_date_ts);
1210                                 dos_filetime_timespec(&mdate_ts);
1211                                 dos_filetime_timespec(&adate_ts);
1212                         }
1213
1214                         create_date = convert_timespec_to_time_t(create_date_ts);
1215                         mdate = convert_timespec_to_time_t(mdate_ts);
1216                         adate = convert_timespec_to_time_t(adate_ts);
1217                         
1218                         DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
1219           
1220                         found = True;
1221
1222                         dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
1223                 }
1224         }
1225
1226         mangle_map(fname,False,True,conn->params);
1227
1228         p = pdata;
1229         last_entry_ptr = p;
1230
1231         nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
1232
1233         switch (info_level) {
1234                 case SMB_FIND_INFO_STANDARD:
1235                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1236                         if(requires_resume_key) {
1237                                 SIVAL(p,0,reskey);
1238                                 p += 4;
1239                         }
1240                         srv_put_dos_date2(p,0,create_date);
1241                         srv_put_dos_date2(p,4,adate);
1242                         srv_put_dos_date2(p,8,mdate);
1243                         SIVAL(p,12,(uint32)file_size);
1244                         SIVAL(p,16,(uint32)allocation_size);
1245                         SSVAL(p,20,mode);
1246                         p += 23;
1247                         nameptr = p;
1248                         p += align_string(outbuf, p, 0);
1249                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1250                         if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1251                                 if (len > 2) {
1252                                         SCVAL(nameptr, -1, len - 2);
1253                                 } else {
1254                                         SCVAL(nameptr, -1, 0);
1255                                 }
1256                         } else {
1257                                 if (len > 1) {
1258                                         SCVAL(nameptr, -1, len - 1);
1259                                 } else {
1260                                         SCVAL(nameptr, -1, 0);
1261                                 }
1262                         }
1263                         p += len;
1264                         break;
1265
1266                 case SMB_FIND_EA_SIZE:
1267                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
1268                         if(requires_resume_key) {
1269                                 SIVAL(p,0,reskey);
1270                                 p += 4;
1271                         }
1272                         srv_put_dos_date2(p,0,create_date);
1273                         srv_put_dos_date2(p,4,adate);
1274                         srv_put_dos_date2(p,8,mdate);
1275                         SIVAL(p,12,(uint32)file_size);
1276                         SIVAL(p,16,(uint32)allocation_size);
1277                         SSVAL(p,20,mode);
1278                         {
1279                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1280                                 SIVAL(p,22,ea_size); /* Extended attributes */
1281                         }
1282                         p += 27;
1283                         nameptr = p - 1;
1284                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
1285                         if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1286                                 if (len > 2) {
1287                                         len -= 2;
1288                                 } else {
1289                                         len = 0;
1290                                 }
1291                         } else {
1292                                 if (len > 1) {
1293                                         len -= 1;
1294                                 } else {
1295                                         len = 0;
1296                                 }
1297                         }
1298                         SCVAL(nameptr,0,len);
1299                         p += len;
1300                         SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1301                         break;
1302
1303                 case SMB_FIND_EA_LIST:
1304                 {
1305                         struct ea_list *file_list = NULL;
1306                         size_t ea_len = 0;
1307
1308                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1309                         if (!name_list) {
1310                                 return False;
1311                         }
1312                         if(requires_resume_key) {
1313                                 SIVAL(p,0,reskey);
1314                                 p += 4;
1315                         }
1316                         srv_put_dos_date2(p,0,create_date);
1317                         srv_put_dos_date2(p,4,adate);
1318                         srv_put_dos_date2(p,8,mdate);
1319                         SIVAL(p,12,(uint32)file_size);
1320                         SIVAL(p,16,(uint32)allocation_size);
1321                         SSVAL(p,20,mode);
1322                         p += 22; /* p now points to the EA area. */
1323
1324                         file_list = get_ea_list_from_file(ea_ctx, conn, NULL, pathreal, &ea_len);
1325                         name_list = ea_list_union(name_list, file_list, &ea_len);
1326
1327                         /* We need to determine if this entry will fit in the space available. */
1328                         /* Max string size is 255 bytes. */
1329                         if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1330                                 /* Move the dirptr back to prev_dirpos */
1331                                 dptr_SeekDir(conn->dirptr, prev_dirpos);
1332                                 *out_of_space = True;
1333                                 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1334                                 return False; /* Not finished - just out of space */
1335                         }
1336
1337                         /* Push the ea_data followed by the name. */
1338                         p += fill_ea_buffer(ea_ctx, p, space_remaining, conn, name_list);
1339                         nameptr = p;
1340                         len = srvstr_push(outbuf, p + 1, fname, -1, STR_TERMINATE | STR_NOALIGN);
1341                         if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1342                                 if (len > 2) {
1343                                         len -= 2;
1344                                 } else {
1345                                         len = 0;
1346                                 }
1347                         } else {
1348                                 if (len > 1) {
1349                                         len -= 1;
1350                                 } else {
1351                                         len = 0;
1352                                 }
1353                         }
1354                         SCVAL(nameptr,0,len);
1355                         p += len + 1;
1356                         SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1357                         break;
1358                 }
1359
1360                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1361                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1362                         was_8_3 = mangle_is_8_3(fname, True, conn->params);
1363                         p += 4;
1364                         SIVAL(p,0,reskey); p += 4;
1365                         put_long_date_timespec(p,create_date_ts); p += 8;
1366                         put_long_date_timespec(p,adate_ts); p += 8;
1367                         put_long_date_timespec(p,mdate_ts); p += 8;
1368                         put_long_date_timespec(p,mdate_ts); p += 8;
1369                         SOFF_T(p,0,file_size); p += 8;
1370                         SOFF_T(p,0,allocation_size); p += 8;
1371                         SIVAL(p,0,nt_extmode); p += 4;
1372                         q = p; p += 4; /* q is placeholder for name length. */
1373                         {
1374                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1375                                 SIVAL(p,0,ea_size); /* Extended attributes */
1376                                 p += 4;
1377                         }
1378                         /* Clear the short name buffer. This is
1379                          * IMPORTANT as not doing so will trigger
1380                          * a Win2k client bug. JRA.
1381                          */
1382                         if (!was_8_3 && check_mangled_names) {
1383                                 pstring mangled_name;
1384                                 pstrcpy(mangled_name, fname);
1385                                 mangle_map(mangled_name,True,True,
1386                                            conn->params);
1387                                 mangled_name[12] = 0;
1388                                 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1389                                 if (len < 24) {
1390                                         memset(p + 2 + len,'\0',24 - len);
1391                                 }
1392                                 SSVAL(p, 0, len);
1393                         } else {
1394                                 memset(p,'\0',26);
1395                         }
1396                         p += 2 + 24;
1397                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1398                         SIVAL(q,0,len);
1399                         p += len;
1400                         SIVAL(p,0,0); /* Ensure any padding is null. */
1401                         len = PTR_DIFF(p, pdata);
1402                         len = (len + 3) & ~3;
1403                         SIVAL(pdata,0,len);
1404                         p = pdata + len;
1405                         break;
1406
1407                 case SMB_FIND_FILE_DIRECTORY_INFO:
1408                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1409                         p += 4;
1410                         SIVAL(p,0,reskey); p += 4;
1411                         put_long_date_timespec(p,create_date_ts); p += 8;
1412                         put_long_date_timespec(p,adate_ts); p += 8;
1413                         put_long_date_timespec(p,mdate_ts); p += 8;
1414                         put_long_date_timespec(p,mdate_ts); p += 8;
1415                         SOFF_T(p,0,file_size); p += 8;
1416                         SOFF_T(p,0,allocation_size); p += 8;
1417                         SIVAL(p,0,nt_extmode); p += 4;
1418                         len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII);
1419                         SIVAL(p,0,len);
1420                         p += 4 + len;
1421                         SIVAL(p,0,0); /* Ensure any padding is null. */
1422                         len = PTR_DIFF(p, pdata);
1423                         len = (len + 3) & ~3;
1424                         SIVAL(pdata,0,len);
1425                         p = pdata + len;
1426                         break;
1427       
1428                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1429                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1430                         p += 4;
1431                         SIVAL(p,0,reskey); p += 4;
1432                         put_long_date_timespec(p,create_date_ts); p += 8;
1433                         put_long_date_timespec(p,adate_ts); p += 8;
1434                         put_long_date_timespec(p,mdate_ts); p += 8;
1435                         put_long_date_timespec(p,mdate_ts); p += 8;
1436                         SOFF_T(p,0,file_size); p += 8;
1437                         SOFF_T(p,0,allocation_size); p += 8;
1438                         SIVAL(p,0,nt_extmode); p += 4;
1439                         q = p; p += 4; /* q is placeholder for name length. */
1440                         {
1441                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1442                                 SIVAL(p,0,ea_size); /* Extended attributes */
1443                                 p +=4;
1444                         }
1445                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1446                         SIVAL(q, 0, len);
1447                         p += len;
1448
1449                         SIVAL(p,0,0); /* Ensure any padding is null. */
1450                         len = PTR_DIFF(p, pdata);
1451                         len = (len + 3) & ~3;
1452                         SIVAL(pdata,0,len);
1453                         p = pdata + len;
1454                         break;
1455
1456                 case SMB_FIND_FILE_NAMES_INFO:
1457                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1458                         p += 4;
1459                         SIVAL(p,0,reskey); p += 4;
1460                         p += 4;
1461                         /* this must *not* be null terminated or w2k gets in a loop trying to set an
1462                            acl on a dir (tridge) */
1463                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1464                         SIVAL(p, -4, len);
1465                         p += len;
1466                         SIVAL(p,0,0); /* Ensure any padding is null. */
1467                         len = PTR_DIFF(p, pdata);
1468                         len = (len + 3) & ~3;
1469                         SIVAL(pdata,0,len);
1470                         p = pdata + len;
1471                         break;
1472
1473                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1474                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1475                         p += 4;
1476                         SIVAL(p,0,reskey); p += 4;
1477                         put_long_date_timespec(p,create_date_ts); p += 8;
1478                         put_long_date_timespec(p,adate_ts); p += 8;
1479                         put_long_date_timespec(p,mdate_ts); p += 8;
1480                         put_long_date_timespec(p,mdate_ts); p += 8;
1481                         SOFF_T(p,0,file_size); p += 8;
1482                         SOFF_T(p,0,allocation_size); p += 8;
1483                         SIVAL(p,0,nt_extmode); p += 4;
1484                         q = p; p += 4; /* q is placeholder for name length. */
1485                         {
1486                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1487                                 SIVAL(p,0,ea_size); /* Extended attributes */
1488                                 p +=4;
1489                         }
1490                         SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1491                         SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
1492                         SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
1493                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1494                         SIVAL(q, 0, len);
1495                         p += len; 
1496                         SIVAL(p,0,0); /* Ensure any padding is null. */
1497                         len = PTR_DIFF(p, pdata);
1498                         len = (len + 3) & ~3;
1499                         SIVAL(pdata,0,len);
1500                         p = pdata + len;
1501                         break;
1502
1503                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1504                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1505                         was_8_3 = mangle_is_8_3(fname, True, conn->params);
1506                         p += 4;
1507                         SIVAL(p,0,reskey); p += 4;
1508                         put_long_date_timespec(p,create_date_ts); p += 8;
1509                         put_long_date_timespec(p,adate_ts); p += 8;
1510                         put_long_date_timespec(p,mdate_ts); p += 8;
1511                         put_long_date_timespec(p,mdate_ts); p += 8;
1512                         SOFF_T(p,0,file_size); p += 8;
1513                         SOFF_T(p,0,allocation_size); p += 8;
1514                         SIVAL(p,0,nt_extmode); p += 4;
1515                         q = p; p += 4; /* q is placeholder for name length */
1516                         {
1517                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1518                                 SIVAL(p,0,ea_size); /* Extended attributes */
1519                                 p +=4;
1520                         }
1521                         /* Clear the short name buffer. This is
1522                          * IMPORTANT as not doing so will trigger
1523                          * a Win2k client bug. JRA.
1524                          */
1525                         if (!was_8_3 && check_mangled_names) {
1526                                 pstring mangled_name;
1527                                 pstrcpy(mangled_name, fname);
1528                                 mangle_map(mangled_name,True,True,
1529                                            conn->params);
1530                                 mangled_name[12] = 0;
1531                                 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1532                                 SSVAL(p, 0, len);
1533                                 if (len < 24) {
1534                                         memset(p + 2 + len,'\0',24 - len);
1535                                 }
1536                                 SSVAL(p, 0, len);
1537                         } else {
1538                                 memset(p,'\0',26);
1539                         }
1540                         p += 26;
1541                         SSVAL(p,0,0); p += 2; /* Reserved ? */
1542                         SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
1543                         SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
1544                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1545                         SIVAL(q,0,len);
1546                         p += len;
1547                         SIVAL(p,0,0); /* Ensure any padding is null. */
1548                         len = PTR_DIFF(p, pdata);
1549                         len = (len + 3) & ~3;
1550                         SIVAL(pdata,0,len);
1551                         p = pdata + len;
1552                         break;
1553
1554                 /* CIFS UNIX Extension. */
1555
1556                 case SMB_FIND_FILE_UNIX:
1557                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1558                         p+= 4;
1559                         SIVAL(p,0,reskey); p+= 4;    /* Used for continuing search. */
1560
1561                         /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1562                         SOFF_T(p,0,get_file_size(sbuf));             /* File size 64 Bit */
1563                         p+= 8;
1564
1565                         SOFF_T(p,0,get_allocation_size(conn,NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
1566                         p+= 8;
1567
1568                         put_long_date_timespec(p,get_ctimespec(&sbuf));       /* Inode change Time 64 Bit */
1569                         put_long_date_timespec(p+8,get_atimespec(&sbuf));     /* Last access time 64 Bit */
1570                         put_long_date_timespec(p+16,get_mtimespec(&sbuf));    /* Last modification time 64 Bit */
1571                         p+= 24;
1572
1573                         SIVAL(p,0,sbuf.st_uid);               /* user id for the owner */
1574                         SIVAL(p,4,0);
1575                         p+= 8;
1576
1577                         SIVAL(p,0,sbuf.st_gid);               /* group id of owner */
1578                         SIVAL(p,4,0);
1579                         p+= 8;
1580
1581                         SIVAL(p,0,unix_filetype(sbuf.st_mode));
1582                         p+= 4;
1583
1584                         SIVAL(p,0,unix_dev_major(sbuf.st_rdev));   /* Major device number if type is device */
1585                         SIVAL(p,4,0);
1586                         p+= 8;
1587
1588                         SIVAL(p,0,unix_dev_minor(sbuf.st_rdev));   /* Minor device number if type is device */
1589                         SIVAL(p,4,0);
1590                         p+= 8;
1591
1592                         SINO_T_VAL(p,0,(SMB_INO_T)sbuf.st_ino);   /* inode number */
1593                         p+= 8;
1594
1595                         SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode));     /* Standard UNIX file permissions */
1596                         SIVAL(p,4,0);
1597                         p+= 8;
1598
1599                         SIVAL(p,0,sbuf.st_nlink);             /* number of hard links */
1600                         SIVAL(p,4,0);
1601                         p+= 8;
1602
1603                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1604                         p += len;
1605                         SIVAL(p,0,0); /* Ensure any padding is null. */
1606
1607                         len = PTR_DIFF(p, pdata);
1608                         len = (len + 3) & ~3;
1609                         SIVAL(pdata,0,len);     /* Offset from this structure to the beginning of the next one */
1610                         p = pdata + len;
1611                         /* End of SMB_QUERY_FILE_UNIX_BASIC */
1612
1613                         break;
1614
1615                 default:      
1616                         return(False);
1617         }
1618
1619
1620         if (PTR_DIFF(p,pdata) > space_remaining) {
1621                 /* Move the dirptr back to prev_dirpos */
1622                 dptr_SeekDir(conn->dirptr, prev_dirpos);
1623                 *out_of_space = True;
1624                 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1625                 return False; /* Not finished - just out of space */
1626         }
1627
1628         /* Setup the last entry pointer, as an offset from base_data */
1629         *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1630         /* Advance the data pointer to the next slot */
1631         *ppdata = p;
1632
1633         return(found);
1634 }
1635
1636 /****************************************************************************
1637  Reply to a TRANS2_FINDFIRST.
1638 ****************************************************************************/
1639
1640 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,  
1641                                 char **pparams, int total_params, char **ppdata, int total_data,
1642                                 unsigned int max_data_bytes)
1643 {
1644         /* We must be careful here that we don't return more than the
1645                 allowed number of data bytes. If this means returning fewer than
1646                 maxentries then so be it. We assume that the redirector has
1647                 enough room for the fixed number of parameter bytes it has
1648                 requested. */
1649         char *params = *pparams;
1650         char *pdata = *ppdata;
1651         uint32 dirtype = SVAL(params,0);
1652         int maxentries = SVAL(params,2);
1653         uint16 findfirst_flags = SVAL(params,4);
1654         BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1655         BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1656         BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1657         int info_level = SVAL(params,6);
1658         pstring directory;
1659         pstring mask;
1660         char *p;
1661         int last_entry_off=0;
1662         int dptr_num = -1;
1663         int numentries = 0;
1664         int i;
1665         BOOL finished = False;
1666         BOOL dont_descend = False;
1667         BOOL out_of_space = False;
1668         int space_remaining;
1669         BOOL bad_path = False;
1670         BOOL mask_contains_wcard = False;
1671         SMB_STRUCT_STAT sbuf;
1672         TALLOC_CTX *ea_ctx = NULL;
1673         struct ea_list *ea_list = NULL;
1674         NTSTATUS ntstatus = NT_STATUS_OK;
1675
1676         if (total_params < 12) {
1677                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1678         }
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), -1, 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 = SVAL(params,0);
1920         int maxentries = SVAL(params,2);
1921         uint16 info_level = SVAL(params,4);
1922         uint32 resume_key = IVAL(params,6);
1923         uint16 findnext_flags = SVAL(params,10);
1924         BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
1925         BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1926         BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1927         BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
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 < 12) {
1945                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1946         }
1947
1948         *mask = *directory = *resume_name = 0;
1949
1950         srvstr_get_path_wcard(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, &mask_contains_wcard);
1951         if (!NT_STATUS_IS_OK(ntstatus)) {
1952                 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
1953                    complain (it thinks we're asking for the directory above the shared
1954                    path or an invalid name). Catch this as the resume name is only compared, never used in
1955                    a file access. JRA. */
1956                 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) {
1957                         pstrcpy(resume_name, "..");
1958                 } else if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_NAME_INVALID)) {
1959                         pstrcpy(resume_name, ".");
1960                 } else {
1961                         return ERROR_NT(ntstatus);
1962                 }
1963         }
1964
1965         DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1966 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1967 resume_key = %d resume name = %s continue=%d level = %d\n",
1968                 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end, 
1969                 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1970
1971         if (!maxentries) {
1972                 /* W2K3 seems to treat zero as 1. */
1973                 maxentries = 1;
1974         }
1975
1976         switch (info_level) {
1977                 case SMB_FIND_INFO_STANDARD:
1978                 case SMB_FIND_EA_SIZE:
1979                 case SMB_FIND_EA_LIST:
1980                 case SMB_FIND_FILE_DIRECTORY_INFO:
1981                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1982                 case SMB_FIND_FILE_NAMES_INFO:
1983                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1984                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1985                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1986                         break;
1987                 case SMB_FIND_FILE_UNIX:
1988                         if (!lp_unix_extensions()) {
1989                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
1990                         }
1991                         break;
1992                 default:
1993                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
1994         }
1995
1996         if (info_level == SMB_FIND_EA_LIST) {
1997                 uint32 ea_size;
1998
1999                 if (total_data < 4) {
2000                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2001                 }
2002
2003                 ea_size = IVAL(pdata,0);
2004                 if (ea_size != total_data) {
2005                         DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2006 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2007                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2008                 }
2009                                                                                                                                                      
2010                 if (!lp_ea_support(SNUM(conn))) {
2011                         return ERROR_DOS(ERRDOS,ERReasnotsupported);
2012                 }
2013                                                                                                                                                      
2014                 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
2015                         return ERROR_NT(NT_STATUS_NO_MEMORY);
2016                 }
2017
2018                 /* Pull out the list of names. */
2019                 ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
2020                 if (!ea_list) {
2021                         talloc_destroy(ea_ctx);
2022                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2023                 }
2024         }
2025
2026         *ppdata = (char *)SMB_REALLOC(
2027                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2028         if(*ppdata == NULL) {
2029                 talloc_destroy(ea_ctx);
2030                 return ERROR_NT(NT_STATUS_NO_MEMORY);
2031         }
2032
2033         pdata = *ppdata;
2034
2035         /* Realloc the params space */
2036         *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
2037         if(*pparams == NULL ) {
2038                 talloc_destroy(ea_ctx);
2039                 return ERROR_NT(NT_STATUS_NO_MEMORY);
2040         }
2041
2042         params = *pparams;
2043
2044         /* Check that the dptr is valid */
2045         if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
2046                 talloc_destroy(ea_ctx);
2047                 return ERROR_DOS(ERRDOS,ERRnofiles);
2048         }
2049
2050         string_set(&conn->dirpath,dptr_path(dptr_num));
2051
2052         /* Get the wildcard mask from the dptr */
2053         if((p = dptr_wcard(dptr_num))== NULL) {
2054                 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
2055                 talloc_destroy(ea_ctx);
2056                 return ERROR_DOS(ERRDOS,ERRnofiles);
2057         }
2058
2059         pstrcpy(mask, p);
2060         pstrcpy(directory,conn->dirpath);
2061
2062         /* Get the attr mask from the dptr */
2063         dirtype = dptr_attr(dptr_num);
2064
2065         DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2066                 dptr_num, mask, dirtype, 
2067                 (long)conn->dirptr,
2068                 dptr_TellDir(conn->dirptr)));
2069
2070         /* We don't need to check for VOL here as this is returned by 
2071                 a different TRANS2 call. */
2072
2073         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
2074         if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2075                 dont_descend = True;
2076     
2077         p = pdata;
2078         space_remaining = max_data_bytes;
2079         out_of_space = False;
2080
2081         /* 
2082          * Seek to the correct position. We no longer use the resume key but
2083          * depend on the last file name instead.
2084          */
2085
2086         if(*resume_name && !continue_bit) {
2087                 SMB_STRUCT_STAT st;
2088
2089                 long current_pos = 0;
2090                 /*
2091                  * Remember, mangle_map is called by
2092                  * get_lanman2_dir_entry(), so the resume name
2093                  * could be mangled. Ensure we check the unmangled name.
2094                  */
2095
2096                 if (mangle_is_mangled(resume_name, conn->params)) {
2097                         mangle_check_cache(resume_name, sizeof(resume_name)-1,
2098                                            conn->params);
2099                 }
2100
2101                 /*
2102                  * Fix for NT redirector problem triggered by resume key indexes
2103                  * changing between directory scans. We now return a resume key of 0
2104                  * and instead look for the filename to continue from (also given
2105                  * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2106                  * findfirst/findnext (as is usual) then the directory pointer
2107                  * should already be at the correct place.
2108                  */
2109
2110                 finished = !dptr_SearchDir(conn->dirptr, resume_name, &current_pos, &st);
2111         } /* end if resume_name && !continue_bit */
2112
2113         for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
2114                 BOOL got_exact_match = False;
2115
2116                 /* this is a heuristic to avoid seeking the dirptr except when 
2117                         absolutely necessary. It allows for a filename of about 40 chars */
2118                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2119                         out_of_space = True;
2120                         finished = False;
2121                 } else {
2122                         finished = !get_lanman2_dir_entry(conn,
2123                                                 inbuf, outbuf,
2124                                                 mask,dirtype,info_level,
2125                                                 requires_resume_key,dont_descend,
2126                                                 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
2127                                                 &last_entry_off, ea_list, ea_ctx);
2128                 }
2129
2130                 if (finished && out_of_space)
2131                         finished = False;
2132
2133                 if (!finished && !out_of_space)
2134                         numentries++;
2135
2136                 /*
2137                  * As an optimisation if we know we aren't looking
2138                  * for a wildcard name (ie. the name matches the wildcard exactly)
2139                  * then we can finish on any (first) match.
2140                  * This speeds up large directory searches. JRA.
2141                  */
2142
2143                 if(got_exact_match)
2144                         finished = True;
2145
2146                 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2147         }
2148   
2149         talloc_destroy(ea_ctx);
2150
2151         /* Check if we can close the dirptr */
2152         if(close_after_request || (finished && close_if_end)) {
2153                 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2154                 dptr_close(&dptr_num); /* This frees up the saved mask */
2155         }
2156
2157         /* Set up the return parameter block */
2158         SSVAL(params,0,numentries);
2159         SSVAL(params,2,finished);
2160         SSVAL(params,4,0); /* Never an EA error */
2161         SSVAL(params,6,last_entry_off);
2162
2163         send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata), max_data_bytes);
2164
2165         if ((! *directory) && dptr_path(dptr_num))
2166                 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
2167
2168         DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2169                 smb_fn_name(CVAL(inbuf,smb_com)), 
2170                 mask, directory, dirtype, numentries ) );
2171
2172         return(-1);
2173 }
2174
2175 /****************************************************************************
2176  Reply to a TRANS2_QFSINFO (query filesystem info).
2177 ****************************************************************************/
2178
2179 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2180                                         char **pparams, int total_params, char **ppdata, int total_data,
2181                                         unsigned int max_data_bytes)
2182 {
2183         char *pdata = *ppdata;
2184         char *params = *pparams;
2185         uint16 info_level = SVAL(params,0);
2186         int data_len, len;
2187         SMB_STRUCT_STAT st;
2188         char *vname = volume_label(SNUM(conn));
2189         int snum = SNUM(conn);
2190         char *fstype = lp_fstype(SNUM(conn));
2191         int quota_flag = 0;
2192
2193         DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
2194
2195         if(SMB_VFS_STAT(conn,".",&st)!=0) {
2196                 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
2197                 return ERROR_DOS(ERRSRV,ERRinvdevice);
2198         }
2199
2200         *ppdata = (char *)SMB_REALLOC(
2201                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2202         if (*ppdata == NULL ) {
2203                 return ERROR_NT(NT_STATUS_NO_MEMORY);
2204         }
2205
2206         pdata = *ppdata;
2207         memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2208
2209         switch (info_level) {
2210                 case SMB_INFO_ALLOCATION:
2211                 {
2212                         SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2213                         data_len = 18;
2214                         if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2215                                 return(UNIXERROR(ERRHRD,ERRgeneral));
2216                         }
2217
2218                         block_size = lp_block_size(snum);
2219                         if (bsize < block_size) {
2220                                 SMB_BIG_UINT factor = block_size/bsize;
2221                                 bsize = block_size;
2222                                 dsize /= factor;
2223                                 dfree /= factor;
2224                         }
2225                         if (bsize > block_size) {
2226                                 SMB_BIG_UINT factor = bsize/block_size;
2227                                 bsize = block_size;
2228                                 dsize *= factor;
2229                                 dfree *= factor;
2230                         }
2231                         bytes_per_sector = 512;
2232                         sectors_per_unit = bsize/bytes_per_sector;
2233
2234                         DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2235 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2236                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2237
2238                         SIVAL(pdata,l1_idFileSystem,st.st_dev);
2239                         SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2240                         SIVAL(pdata,l1_cUnit,dsize);
2241                         SIVAL(pdata,l1_cUnitAvail,dfree);
2242                         SSVAL(pdata,l1_cbSector,bytes_per_sector);
2243                         break;
2244                 }
2245
2246                 case SMB_INFO_VOLUME:
2247                         /* Return volume name */
2248                         /* 
2249                          * Add volume serial number - hash of a combination of
2250                          * the called hostname and the service name.
2251                          */
2252                         SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2253                         /*
2254                          * Win2k3 and previous mess this up by sending a name length
2255                          * one byte short. I believe only older clients (OS/2 Win9x) use
2256                          * this call so try fixing this by adding a terminating null to
2257                          * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2258                          */
2259                         len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN|STR_TERMINATE);
2260                         SCVAL(pdata,l2_vol_cch,len);
2261                         data_len = l2_vol_szVolLabel + len;
2262                         DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
2263                                 (unsigned)st.st_ctime, len, vname));
2264                         break;
2265
2266                 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2267                 case SMB_FS_ATTRIBUTE_INFORMATION:
2268
2269
2270 #if defined(HAVE_SYS_QUOTAS)
2271                         quota_flag = FILE_VOLUME_QUOTAS;
2272 #endif
2273
2274                         SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2275                                 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
2276                                 quota_flag); /* FS ATTRIBUTES */
2277
2278                         SIVAL(pdata,4,255); /* Max filename component length */
2279                         /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2280                                 and will think we can't do long filenames */
2281                         len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
2282                         SIVAL(pdata,8,len);
2283                         data_len = 12 + len;
2284                         break;
2285
2286                 case SMB_QUERY_FS_LABEL_INFO:
2287                 case SMB_FS_LABEL_INFORMATION:
2288                         len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
2289                         data_len = 4 + len;
2290                         SIVAL(pdata,0,len);
2291                         break;
2292
2293                 case SMB_QUERY_FS_VOLUME_INFO:      
2294                 case SMB_FS_VOLUME_INFORMATION:
2295
2296                         /* 
2297                          * Add volume serial number - hash of a combination of
2298                          * the called hostname and the service name.
2299                          */
2300                         SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ 
2301                                 (str_checksum(get_local_machine_name())<<16));
2302
2303                         len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
2304                         SIVAL(pdata,12,len);
2305                         data_len = 18+len;
2306                         DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", 
2307                                 (int)strlen(vname),vname, lp_servicename(snum)));
2308                         break;
2309
2310                 case SMB_QUERY_FS_SIZE_INFO:
2311                 case SMB_FS_SIZE_INFORMATION:
2312                 {
2313                         SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2314                         data_len = 24;
2315                         if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2316                                 return(UNIXERROR(ERRHRD,ERRgeneral));
2317                         }
2318                         block_size = lp_block_size(snum);
2319                         if (bsize < block_size) {
2320                                 SMB_BIG_UINT factor = block_size/bsize;
2321                                 bsize = block_size;
2322                                 dsize /= factor;
2323                                 dfree /= factor;
2324                         }
2325                         if (bsize > block_size) {
2326                                 SMB_BIG_UINT factor = bsize/block_size;
2327                                 bsize = block_size;
2328                                 dsize *= factor;
2329                                 dfree *= factor;
2330                         }
2331                         bytes_per_sector = 512;
2332                         sectors_per_unit = bsize/bytes_per_sector;
2333                         DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2334 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2335                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2336                         SBIG_UINT(pdata,0,dsize);
2337                         SBIG_UINT(pdata,8,dfree);
2338                         SIVAL(pdata,16,sectors_per_unit);
2339                         SIVAL(pdata,20,bytes_per_sector);
2340                         break;
2341                 }
2342
2343                 case SMB_FS_FULL_SIZE_INFORMATION:
2344                 {
2345                         SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2346                         data_len = 32;
2347                         if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2348                                 return(UNIXERROR(ERRHRD,ERRgeneral));
2349                         }
2350                         block_size = lp_block_size(snum);
2351                         if (bsize < block_size) {
2352                                 SMB_BIG_UINT factor = block_size/bsize;
2353                                 bsize = block_size;
2354                                 dsize /= factor;
2355                                 dfree /= factor;
2356                         }
2357                         if (bsize > block_size) {
2358                                 SMB_BIG_UINT factor = bsize/block_size;
2359                                 bsize = block_size;
2360                                 dsize *= factor;
2361                                 dfree *= factor;
2362                         }
2363                         bytes_per_sector = 512;
2364                         sectors_per_unit = bsize/bytes_per_sector;
2365                         DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2366 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2367                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2368                         SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2369                         SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2370                         SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2371                         SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2372                         SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2373                         break;
2374                 }
2375
2376                 case SMB_QUERY_FS_DEVICE_INFO:
2377                 case SMB_FS_DEVICE_INFORMATION:
2378                         data_len = 8;
2379                         SIVAL(pdata,0,0); /* dev type */
2380                         SIVAL(pdata,4,0); /* characteristics */
2381                         break;
2382
2383 #ifdef HAVE_SYS_QUOTAS
2384                 case SMB_FS_QUOTA_INFORMATION:
2385                 /* 
2386                  * what we have to send --metze:
2387                  *
2388                  * Unknown1:            24 NULL bytes
2389                  * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
2390                  * Hard Quota Limit:    8 bytes seems like SMB_BIG_UINT or so
2391                  * Quota Flags:         2 byte :
2392                  * Unknown3:            6 NULL bytes
2393                  *
2394                  * 48 bytes total
2395                  * 
2396                  * details for Quota Flags:
2397                  * 
2398                  * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2399                  * 0x0010 Log Warn:  log if the user exceeds his Soft Quota
2400                  * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2401                  * 0x0001 Enable Quotas: enable quota for this fs
2402                  *
2403                  */
2404                 {
2405                         /* we need to fake up a fsp here,
2406                          * because its not send in this call
2407                          */
2408                         files_struct fsp;
2409                         SMB_NTQUOTA_STRUCT quotas;
2410                         
2411                         ZERO_STRUCT(fsp);
2412                         ZERO_STRUCT(quotas);
2413                         
2414                         fsp.conn = conn;
2415                         fsp.fnum = -1;
2416                         
2417                         /* access check */
2418                         if (current_user.ut.uid != 0) {
2419                                 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2420                                         lp_servicename(SNUM(conn)),conn->user));
2421                                 return ERROR_DOS(ERRDOS,ERRnoaccess);
2422                         }
2423                         
2424                         if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
2425                                 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2426                                 return ERROR_DOS(ERRSRV,ERRerror);
2427                         }
2428
2429                         data_len = 48;
2430
2431                         DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));          
2432                 
2433                         /* Unknown1 24 NULL bytes*/
2434                         SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
2435                         SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
2436                         SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
2437                 
2438                         /* Default Soft Quota 8 bytes */
2439                         SBIG_UINT(pdata,24,quotas.softlim);
2440
2441                         /* Default Hard Quota 8 bytes */
2442                         SBIG_UINT(pdata,32,quotas.hardlim);
2443         
2444                         /* Quota flag 2 bytes */
2445                         SSVAL(pdata,40,quotas.qflags);
2446                 
2447                         /* Unknown3 6 NULL bytes */
2448                         SSVAL(pdata,42,0);
2449                         SIVAL(pdata,44,0);
2450                         
2451                         break;
2452                 }
2453 #endif /* HAVE_SYS_QUOTAS */
2454                 case SMB_FS_OBJECTID_INFORMATION:
2455                         data_len = 64;
2456                         break;
2457
2458                 /*
2459                  * Query the version and capabilities of the CIFS UNIX extensions
2460                  * in use.
2461                  */
2462
2463                 case SMB_QUERY_CIFS_UNIX_INFO:
2464                         if (!lp_unix_extensions()) {
2465                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2466                         }
2467                         data_len = 12;
2468                         SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2469                         SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2470                         /* We have POSIX ACLs, pathname and locking capability. */
2471                         SBIG_UINT(pdata,4,((SMB_BIG_UINT)(
2472                                         CIFS_UNIX_POSIX_ACLS_CAP|
2473                                         CIFS_UNIX_POSIX_PATHNAMES_CAP|
2474                                         CIFS_UNIX_FCNTL_LOCKS_CAP)));
2475                         break;
2476
2477                 case SMB_QUERY_POSIX_FS_INFO:
2478                 {
2479                         int rc;
2480                         vfs_statvfs_struct svfs;
2481
2482                         if (!lp_unix_extensions()) {
2483                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2484                         }
2485
2486                         rc = SMB_VFS_STATVFS(conn, ".", &svfs);
2487
2488                         if (!rc) {
2489                                 data_len = 56;
2490                                 SIVAL(pdata,0,svfs.OptimalTransferSize);
2491                                 SIVAL(pdata,4,svfs.BlockSize);
2492                                 SBIG_UINT(pdata,8,svfs.TotalBlocks);
2493                                 SBIG_UINT(pdata,16,svfs.BlocksAvail);
2494                                 SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
2495                                 SBIG_UINT(pdata,32,svfs.TotalFileNodes);
2496                                 SBIG_UINT(pdata,40,svfs.FreeFileNodes);
2497                                 SBIG_UINT(pdata,48,svfs.FsIdentifier);
2498                                 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
2499 #ifdef EOPNOTSUPP
2500                         } else if (rc == EOPNOTSUPP) {
2501                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2502 #endif /* EOPNOTSUPP */
2503                         } else {
2504                                 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2505                                 return ERROR_DOS(ERRSRV,ERRerror);
2506                         }
2507                         break;
2508                 }
2509
2510                 case SMB_MAC_QUERY_FS_INFO:
2511                         /*
2512                          * Thursby MAC extension... ONLY on NTFS filesystems
2513                          * once we do streams then we don't need this
2514                          */
2515                         if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2516                                 data_len = 88;
2517                                 SIVAL(pdata,84,0x100); /* Don't support mac... */
2518                                 break;
2519                         }
2520                         /* drop through */
2521                 default:
2522                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2523         }
2524
2525
2526         send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len, max_data_bytes);
2527
2528         DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
2529
2530         return -1;
2531 }
2532
2533 /****************************************************************************
2534  Reply to a TRANS2_SETFSINFO (set filesystem info).
2535 ****************************************************************************/
2536
2537 static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2538                                         char **pparams, int total_params, char **ppdata, int total_data,
2539                                         unsigned int max_data_bytes)
2540 {
2541         char *pdata = *ppdata;
2542         char *params = *pparams;
2543         uint16 info_level;
2544         int outsize;
2545
2546         DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn))));
2547
2548         /*  */
2549         if (total_params < 4) {
2550                 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2551                         total_params));
2552                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2553         }
2554
2555         info_level = SVAL(params,2);
2556
2557         switch(info_level) {
2558                 case SMB_SET_CIFS_UNIX_INFO:
2559                         {
2560                                 uint16 client_unix_major;
2561                                 uint16 client_unix_minor;
2562                                 uint32 client_unix_cap_low;
2563                                 uint32 client_unix_cap_high;
2564
2565                                 if (!lp_unix_extensions()) {
2566                                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2567                                 }
2568
2569                                 /* There should be 12 bytes of capabilities set. */
2570                                 if (total_data < 8) {
2571                                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2572                                 }
2573                                 client_unix_major = SVAL(pdata,0);
2574                                 client_unix_minor = SVAL(pdata,2);
2575                                 client_unix_cap_low = IVAL(pdata,4);
2576                                 client_unix_cap_high = IVAL(pdata,8);
2577                                 /* Just print these values for now. */
2578                                 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
2579 cap_low = 0x%x, cap_high = 0x%x\n",
2580                                         (unsigned int)client_unix_major,
2581                                         (unsigned int)client_unix_minor,
2582                                         (unsigned int)client_unix_cap_low,
2583                                         (unsigned int)client_unix_cap_high ));
2584
2585                                 /* Here is where we must switch to posix pathname processing... */
2586                                 if (client_unix_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2587                                         lp_set_posix_pathnames();
2588                                         mangle_change_to_posix();
2589                                 }
2590
2591                                 if (client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) {
2592                                         lp_set_posix_cifsx_locktype(POSIX_LOCK);
2593                                 }
2594                                 break;
2595                         }
2596                 case SMB_FS_QUOTA_INFORMATION:
2597                         {
2598                                 files_struct *fsp = NULL;
2599                                 SMB_NTQUOTA_STRUCT quotas;
2600         
2601                                 ZERO_STRUCT(quotas);
2602
2603                                 /* access check */
2604                                 if ((current_user.ut.uid != 0)||!CAN_WRITE(conn)) {
2605                                         DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2606                                                 lp_servicename(SNUM(conn)),conn->user));
2607                                         return ERROR_DOS(ERRSRV,ERRaccess);
2608                                 }
2609
2610                                 /* note: normaly there're 48 bytes,
2611                                  * but we didn't use the last 6 bytes for now 
2612                                  * --metze 
2613                                  */
2614                                 fsp = file_fsp(params,0);
2615                                 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2616                                         DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2617                                         return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2618                                 }
2619
2620                                 if (total_data < 42) {
2621                                         DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2622                                                 total_data));
2623                                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2624                                 }
2625                         
2626                                 /* unknown_1 24 NULL bytes in pdata*/
2627                 
2628                                 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2629                                 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2630 #ifdef LARGE_SMB_OFF_T
2631                                 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2632 #else /* LARGE_SMB_OFF_T */
2633                                 if ((IVAL(pdata,28) != 0)&&
2634                                         ((quotas.softlim != 0xFFFFFFFF)||
2635                                         (IVAL(pdata,28)!=0xFFFFFFFF))) {
2636                                         /* more than 32 bits? */
2637                                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2638                                 }
2639 #endif /* LARGE_SMB_OFF_T */
2640                 
2641                                 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2642                                 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2643 #ifdef LARGE_SMB_OFF_T
2644                                 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2645 #else /* LARGE_SMB_OFF_T */
2646                                 if ((IVAL(pdata,36) != 0)&&
2647                                         ((quotas.hardlim != 0xFFFFFFFF)||
2648                                         (IVAL(pdata,36)!=0xFFFFFFFF))) {
2649                                         /* more than 32 bits? */
2650                                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2651                                 }
2652 #endif /* LARGE_SMB_OFF_T */
2653                 
2654                                 /* quota_flags 2 bytes **/
2655                                 quotas.qflags = SVAL(pdata,40);
2656                 
2657                                 /* unknown_2 6 NULL bytes follow*/
2658                 
2659                                 /* now set the quotas */
2660                                 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
2661                                         DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2662                                         return ERROR_DOS(ERRSRV,ERRerror);
2663                                 }
2664                         
2665                                 break;
2666                         }
2667                 default:
2668                         DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2669                                 info_level));
2670                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2671                         break;
2672         }
2673
2674         /* 
2675          * sending this reply works fine, 
2676          * but I'm not sure it's the same 
2677          * like windows do...
2678          * --metze
2679          */ 
2680         outsize = set_message(outbuf,10,0,True);
2681
2682         return outsize;
2683 }
2684
2685 /****************************************************************************
2686  Utility function to set bad path error.
2687 ****************************************************************************/
2688
2689 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
2690 {
2691         DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2692                         err, (int)bad_path ));
2693
2694         if(err == ENOENT) {
2695                 if (bad_path) {
2696                         return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2697                 } else {
2698                         return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
2699                 }
2700         }
2701         return UNIXERROR(def_class,def_code);
2702 }
2703
2704 #if defined(HAVE_POSIX_ACLS)
2705 /****************************************************************************
2706  Utility function to count the number of entries in a POSIX acl.
2707 ****************************************************************************/
2708
2709 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
2710 {
2711         unsigned int ace_count = 0;
2712         int entry_id = SMB_ACL_FIRST_ENTRY;
2713         SMB_ACL_ENTRY_T entry;
2714
2715         while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2716                 /* get_next... */
2717                 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2718                         entry_id = SMB_ACL_NEXT_ENTRY;
2719                 }
2720                 ace_count++;
2721         }
2722         return ace_count;
2723 }
2724
2725 /****************************************************************************
2726  Utility function to marshall a POSIX acl into wire format.
2727 ****************************************************************************/
2728
2729 static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
2730 {
2731         int entry_id = SMB_ACL_FIRST_ENTRY;
2732         SMB_ACL_ENTRY_T entry;
2733
2734         while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2735                 SMB_ACL_TAG_T tagtype;
2736                 SMB_ACL_PERMSET_T permset;
2737                 unsigned char perms = 0;
2738                 unsigned int own_grp;
2739
2740                 /* get_next... */
2741                 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2742                         entry_id = SMB_ACL_NEXT_ENTRY;
2743                 }
2744
2745                 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
2746                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2747                         return False;
2748                 }
2749
2750                 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
2751                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2752                         return False;
2753                 }
2754
2755                 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
2756                 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
2757                 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
2758
2759                 SCVAL(pdata,1,perms);
2760
2761                 switch (tagtype) {
2762                         case SMB_ACL_USER_OBJ:
2763                                 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
2764                                 own_grp = (unsigned int)pst->st_uid;
2765                                 SIVAL(pdata,2,own_grp);
2766                                 SIVAL(pdata,6,0);
2767                                 break;
2768                         case SMB_ACL_USER:
2769                                 {
2770                                         uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2771                                         if (!puid) {
2772                                                 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2773                                         }
2774                                         own_grp = (unsigned int)*puid;
2775                                         SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
2776                                         SCVAL(pdata,0,SMB_POSIX_ACL_USER);
2777                                         SIVAL(pdata,2,own_grp);
2778                                         SIVAL(pdata,6,0);
2779                                         break;
2780                                 }
2781                         case SMB_ACL_GROUP_OBJ:
2782                                 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
2783                                 own_grp = (unsigned int)pst->st_gid;
2784                                 SIVAL(pdata,2,own_grp);
2785                                 SIVAL(pdata,6,0);
2786                                 break;
2787                         case SMB_ACL_GROUP:
2788                                 {
2789                                         gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2790                                         if (!pgid) {
2791                                                 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2792                                         }
2793                                         own_grp = (unsigned int)*pgid;
2794                                         SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
2795                                         SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
2796                                         SIVAL(pdata,2,own_grp);
2797                                         SIVAL(pdata,6,0);
2798                                         break;
2799                                 }
2800                         case SMB_ACL_MASK:
2801                                 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
2802                                 SIVAL(pdata,2,0xFFFFFFFF);
2803                                 SIVAL(pdata,6,0xFFFFFFFF);
2804                                 break;
2805                         case SMB_ACL_OTHER:
2806                                 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
2807                                 SIVAL(pdata,2,0xFFFFFFFF);
2808                                 SIVAL(pdata,6,0xFFFFFFFF);
2809                                 break;
2810                         default:
2811                                 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
2812                                 return False;
2813                 }
2814                 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
2815         }
2816
2817         return True;
2818 }
2819 #endif
2820
2821 /****************************************************************************
2822  Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2823  file name or file id).
2824 ****************************************************************************/
2825
2826 static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2827                                         unsigned int tran_call,
2828                                         char **pparams, int total_params, char **ppdata, int total_data,
2829                                         unsigned int max_data_bytes)
2830 {
2831         char *params = *pparams;
2832         char *pdata = *ppdata;
2833         uint16 info_level;
2834         int mode=0;
2835         int nlink;
2836         SMB_OFF_T file_size=0;
2837         SMB_BIG_UINT allocation_size=0;
2838         unsigned int data_size = 0;
2839         unsigned int param_size = 2;
2840         SMB_STRUCT_STAT sbuf;
2841         pstring fname, dos_fname;
2842         char *fullpathname;
2843         char *base_name;
2844         char *p;
2845         SMB_OFF_T pos = 0;
2846         BOOL bad_path = False;
2847         BOOL delete_pending = False;
2848         int len;
2849         time_t create_time, mtime, atime;
2850         struct timespec create_time_ts, mtime_ts, atime_ts;
2851         files_struct *fsp = NULL;
2852         TALLOC_CTX *data_ctx = NULL;
2853         struct ea_list *ea_list = NULL;
2854         uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2855         char *lock_data = NULL;
2856
2857         if (!params)
2858                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2859
2860         ZERO_STRUCT(sbuf);
2861
2862         if (tran_call == TRANSACT2_QFILEINFO) {
2863                 if (total_params < 4) {
2864                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2865                 }
2866
2867                 fsp = file_fsp(params,0);
2868                 info_level = SVAL(params,2);
2869
2870                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
2871
2872                 if(fsp && (fsp->fake_file_handle)) {
2873                         /*
2874                          * This is actually for the QUOTA_FAKE_FILE --metze
2875                          */
2876                                                 
2877                         pstrcpy(fname, fsp->fsp_name);
2878                         /* We know this name is ok, it's already passed the checks. */
2879                         
2880                 } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
2881                         /*
2882                          * This is actually a QFILEINFO on a directory
2883                          * handle (returned from an NT SMB). NT5.0 seems
2884                          * to do this call. JRA.
2885                          */
2886                         /* We know this name is ok, it's already passed the checks. */
2887                         pstrcpy(fname, fsp->fsp_name);
2888                   
2889                         if (INFO_LEVEL_IS_UNIX(info_level)) {
2890                                 /* Always do lstat for UNIX calls. */
2891                                 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2892                                         DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2893                                         return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2894                                 }
2895                         } else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
2896                                 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2897                                 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2898                         }
2899
2900                         delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
2901                 } else {
2902                         /*
2903                          * Original code - this is an open file.
2904                          */
2905                         CHECK_FSP(fsp,conn);
2906
2907                         pstrcpy(fname, fsp->fsp_name);
2908                         if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) {
2909                                 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
2910                                 return(UNIXERROR(ERRDOS,ERRbadfid));
2911                         }
2912                         pos = fsp->fh->position_information;
2913                         delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
2914                         access_mask = fsp->access_mask;
2915                 }
2916         } else {
2917                 NTSTATUS status = NT_STATUS_OK;
2918
2919                 /* qpathinfo */
2920                 if (total_params < 6) {
2921                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2922                 }
2923
2924                 info_level = SVAL(params,0);
2925
2926                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
2927
2928                 srvstr_get_path(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE, &status);
2929                 if (!NT_STATUS_IS_OK(status)) {
2930                         return ERROR_NT(status);
2931                 }
2932
2933                 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
2934
2935                 unix_convert(fname,conn,0,&bad_path,&sbuf);
2936                 if (bad_path) {
2937                         return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2938                 }
2939                 if (!check_name(fname,conn)) {
2940                         DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2941                         return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2942                 }
2943
2944                 if (INFO_LEVEL_IS_UNIX(info_level)) {
2945                         /* Always do lstat for UNIX calls. */
2946                         if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2947                                 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2948                                 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2949                         }
2950                 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
2951                         DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2952                         return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2953                 }
2954
2955                 delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
2956                 if (delete_pending) {
2957                         return ERROR_NT(NT_STATUS_DELETE_PENDING);
2958                 }
2959         }
2960
2961         nlink = sbuf.st_nlink;
2962
2963         if ((nlink > 0) && S_ISDIR(sbuf.st_mode)) {
2964                 /* NTFS does not seem to count ".." */
2965                 nlink -= 1;
2966         }
2967
2968         if ((nlink > 0) && delete_pending) {
2969                 nlink -= 1;
2970         }
2971
2972         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
2973                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2974         }
2975
2976         DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2977                 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
2978
2979         p = strrchr_m(fname,'/'); 
2980         if (!p)
2981                 base_name = fname;
2982         else
2983                 base_name = p+1;
2984
2985         mode = dos_mode(conn,fname,&sbuf);
2986         if (!mode)
2987                 mode = FILE_ATTRIBUTE_NORMAL;
2988
2989         fullpathname = fname;
2990         if (!(mode & aDIR))
2991                 file_size = get_file_size(sbuf);
2992
2993         /* Pull out any data sent here before we realloc. */
2994         switch (info_level) {
2995                 case SMB_INFO_QUERY_EAS_FROM_LIST:
2996                 {
2997                         /* Pull any EA list from the data portion. */
2998                         uint32 ea_size;
2999
3000                         if (total_data < 4) {
3001                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3002                         }
3003                         ea_size = IVAL(pdata,0);
3004
3005                         if (total_data > 0 && ea_size != total_data) {
3006                                 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
3007 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
3008                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3009                         }
3010
3011                         if (!lp_ea_support(SNUM(conn))) {
3012                                 return ERROR_DOS(ERRDOS,ERReasnotsupported);
3013                         }
3014
3015                         if ((data_ctx = talloc_init("ea_list")) == NULL) {
3016                                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3017                         }
3018
3019                         /* Pull out the list of names. */
3020                         ea_list = read_ea_name_list(data_ctx, pdata + 4, ea_size - 4);
3021                         if (!ea_list) {
3022                                 talloc_destroy(data_ctx);
3023                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3024                         }
3025                         break;
3026                 }
3027
3028                 case SMB_QUERY_POSIX_LOCK:
3029                 {
3030                         if (fsp == NULL || fsp->fh->fd == -1) {
3031                                 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
3032                         }
3033
3034                         if (total_data != POSIX_LOCK_DATA_SIZE) {
3035                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3036                         }
3037
3038                         if ((data_ctx = talloc_init("lock_request")) == NULL) {
3039                                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3040                         }
3041
3042                         /* Copy the lock range data. */
3043                         lock_data = (char *)talloc_memdup(
3044                                 data_ctx, pdata, total_data);
3045                         if (!lock_data) {
3046                                 talloc_destroy(data_ctx);
3047                                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3048                         }
3049                 }
3050                 default:
3051                         break;
3052         }
3053
3054         *pparams = (char *)SMB_REALLOC(*pparams,2);
3055         if (*pparams == NULL) {
3056                 talloc_destroy(data_ctx);
3057                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3058         }
3059         params = *pparams;
3060         SSVAL(params,0,0);
3061         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
3062         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 
3063         if (*ppdata == NULL ) {
3064                 talloc_destroy(data_ctx);
3065                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3066         }
3067         pdata = *ppdata;
3068
3069         create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
3070         mtime_ts = get_mtimespec(&sbuf);
3071         atime_ts = get_atimespec(&sbuf);
3072
3073         allocation_size = get_allocation_size(conn,fsp,&sbuf);
3074
3075         if (fsp) {
3076                 if (fsp->pending_modtime) {
3077                         /* the pending modtime overrides the current modtime */
3078                         mtime_ts.tv_sec = fsp->pending_modtime;
3079                         mtime_ts.tv_nsec = 0;
3080                 }
3081         } else {
3082                 /* Do we have this path open ? */
3083                 files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino);
3084                 if (fsp1 && fsp1->pending_modtime) {
3085                         /* the pending modtime overrides the current modtime */
3086                         mtime_ts.tv_sec = fsp1->pending_modtime;
3087                         mtime_ts.tv_nsec = 0;
3088                 }
3089                 if (fsp1 && fsp1->initial_allocation_size) {
3090                         allocation_size = get_allocation_size(conn, fsp1, &sbuf);
3091                 }
3092         }
3093
3094         if (lp_dos_filetime_resolution(SNUM(conn))) {
3095                 dos_filetime_timespec(&create_time_ts);
3096                 dos_filetime_timespec(&mtime_ts);
3097                 dos_filetime_timespec(&atime_ts);
3098         }
3099
3100         create_time = convert_timespec_to_time_t(create_time_ts);
3101         mtime = convert_timespec_to_time_t(mtime_ts);
3102         atime = convert_timespec_to_time_t(atime_ts);
3103
3104         /* NT expects the name to be in an exact form of the *full*
3105            filename. See the trans2 torture test */
3106         if (strequal(base_name,".")) {
3107                 pstrcpy(dos_fname, "\\");
3108         } else {
3109                 pstr_sprintf(dos_fname, "\\%s", fname);
3110                 string_replace(dos_fname, '/', '\\');
3111         }
3112
3113         switch (info_level) {
3114                 case SMB_INFO_STANDARD:
3115                         DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
3116                         data_size = 22;
3117                         srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
3118                         srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
3119                         srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
3120                         SIVAL(pdata,l1_cbFile,(uint32)file_size);
3121                         SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
3122                         SSVAL(pdata,l1_attrFile,mode);
3123                         break;
3124
3125                 case SMB_INFO_QUERY_EA_SIZE:
3126                 {
3127                         unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3128                         DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
3129                         data_size = 26;
3130                         srv_put_dos_date2(pdata,0,create_time);
3131                         srv_put_dos_date2(pdata,4,atime);
3132                         srv_put_dos_date2(pdata,8,mtime); /* write time */
3133                         SIVAL(pdata,12,(uint32)file_size);
3134                         SIVAL(pdata,16,(uint32)allocation_size);
3135                         SSVAL(pdata,20,mode);
3136                         SIVAL(pdata,22,ea_size);
3137                         break;
3138                 }
3139
3140                 case SMB_INFO_IS_NAME_VALID:
3141                         DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
3142                         if (tran_call == TRANSACT2_QFILEINFO) {
3143                                 /* os/2 needs this ? really ?*/      
3144                                 return ERROR_DOS(ERRDOS,ERRbadfunc); 
3145                         }
3146                         data_size = 0;
3147                         param_size = 0;
3148                         break;
3149                         
3150                 case SMB_INFO_QUERY_EAS_FROM_LIST:
3151                 {
3152                         size_t total_ea_len = 0;
3153                         struct ea_list *ea_file_list = NULL;
3154
3155                         DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
3156
3157                         ea_file_list = get_ea_list_from_file(data_ctx, conn, fsp, fname, &total_ea_len);
3158                         ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
3159
3160                         if (!ea_list || (total_ea_len > data_size)) {
3161                                 talloc_destroy(data_ctx);
3162                                 data_size = 4;
3163                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
3164                                 break;
3165                         }
3166
3167                         data_size = fill_ea_buffer(data_ctx, pdata, data_size, conn, ea_list);
3168                         talloc_destroy(data_ctx);
3169                         break;
3170                 }
3171
3172                 case SMB_INFO_QUERY_ALL_EAS:
3173                 {
3174                         /* We have data_size bytes to put EA's into. */
3175                         size_t total_ea_len = 0;
3176
3177                         DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
3178
3179                         data_ctx = talloc_init("ea_ctx");
3180                         if (!data_ctx) {
3181                                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3182                         }
3183
3184                         ea_list = get_ea_list_from_file(data_ctx, conn, fsp, fname, &total_ea_len);
3185                         if (!ea_list || (total_ea_len > data_size)) {
3186                                 talloc_destroy(data_ctx);
3187                                 data_size = 4;
3188                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
3189                                 break;
3190                         }
3191
3192                         data_size = fill_ea_buffer(data_ctx, pdata, data_size, conn, ea_list);
3193                         talloc_destroy(data_ctx);
3194                         break;
3195                 }
3196
3197                 case SMB_FILE_BASIC_INFORMATION:
3198                 case SMB_QUERY_FILE_BASIC_INFO:
3199
3200                         if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
3201                                 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
3202                                 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
3203                         } else {
3204                                 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
3205                                 data_size = 40;
3206                                 SIVAL(pdata,36,0);
3207                         }
3208                         put_long_date_timespec(pdata,create_time_ts);
3209                         put_long_date_timespec(pdata+8,atime_ts);
3210                         put_long_date_timespec(pdata+16,mtime_ts); /* write time */
3211                         put_long_date_timespec(pdata+24,mtime_ts); /* change time */
3212                         SIVAL(pdata,32,mode);
3213
3214                         DEBUG(5,("SMB_QFBI - "));
3215                         DEBUG(5,("create: %s ", ctime(&create_time)));
3216                         DEBUG(5,("access: %s ", ctime(&atime)));
3217                         DEBUG(5,("write: %s ", ctime(&mtime)));
3218                         DEBUG(5,("change: %s ", ctime(&mtime)));
3219                         DEBUG(5,("mode: %x\n", mode));
3220                         break;
3221
3222                 case SMB_FILE_STANDARD_INFORMATION:
3223                 case SMB_QUERY_FILE_STANDARD_INFO:
3224
3225                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
3226                         data_size = 24;
3227                         SOFF_T(pdata,0,allocation_size);
3228                         SOFF_T(pdata,8,file_size);
3229                         SIVAL(pdata,16,nlink);
3230                         SCVAL(pdata,20,delete_pending?1:0);
3231                         SCVAL(pdata,21,(mode&aDIR)?1:0);
3232                         SSVAL(pdata,22,0); /* Padding. */
3233                         break;
3234
3235                 case SMB_FILE_EA_INFORMATION:
3236                 case SMB_QUERY_FILE_EA_INFO:
3237                 {
3238                         unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3239                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
3240                         data_size = 4;
3241                         SIVAL(pdata,0,ea_size);
3242                         break;
3243                 }
3244
3245                 /* Get the 8.3 name - used if NT SMB was negotiated. */
3246                 case SMB_QUERY_FILE_ALT_NAME_INFO:
3247                 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
3248                 {
3249                         pstring short_name;
3250
3251                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
3252                         pstrcpy(short_name,base_name);
3253                         /* Mangle if not already 8.3 */
3254                         if(!mangle_is_8_3(short_name, True, conn->params)) {
3255                                 mangle_map(short_name,True,True,conn->params);
3256                         }
3257                         len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
3258                         data_size = 4 + len;
3259                         SIVAL(pdata,0,len);
3260                         break;
3261                 }
3262
3263                 case SMB_QUERY_FILE_NAME_INFO:
3264                         /*
3265                           this must be *exactly* right for ACLs on mapped drives to work
3266                          */
3267                         len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
3268                         DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
3269                         data_size = 4 + len;
3270                         SIVAL(pdata,0,len);
3271                         break;
3272
3273                 case SMB_FILE_ALLOCATION_INFORMATION:
3274                 case SMB_QUERY_FILE_ALLOCATION_INFO:
3275                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
3276                         data_size = 8;
3277                         SOFF_T(pdata,0,allocation_size);
3278                         break;
3279
3280                 case SMB_FILE_END_OF_FILE_INFORMATION:
3281                 case SMB_QUERY_FILE_END_OF_FILEINFO:
3282                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
3283                         data_size = 8;
3284                         SOFF_T(pdata,0,file_size);
3285                         break;
3286
3287                 case SMB_QUERY_FILE_ALL_INFO:
3288                 case SMB_FILE_ALL_INFORMATION:
3289                 {
3290                         unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3291                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
3292                         put_long_date_timespec(pdata,create_time_ts);
3293                         put_long_date_timespec(pdata+8,atime_ts);
3294                         put_long_date_timespec(pdata+16,mtime_ts); /* write time */
3295                         put_long_date_timespec(pdata+24,mtime_ts); /* change time */
3296                         SIVAL(pdata,32,mode);
3297                         SIVAL(pdata,36,0); /* padding. */
3298                         pdata += 40;
3299                         SOFF_T(pdata,0,allocation_size);
3300                         SOFF_T(pdata,8,file_size);
3301                         SIVAL(pdata,16,nlink);
3302                         SCVAL(pdata,20,delete_pending);
3303                         SCVAL(pdata,21,(mode&aDIR)?1:0);
3304                         SSVAL(pdata,22,0);
3305                         pdata += 24;
3306                         SIVAL(pdata,0,ea_size);
3307                         pdata += 4; /* EA info */
3308                         len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
3309                         SIVAL(pdata,0,len);
3310                         pdata += 4 + len;
3311                         data_size = PTR_DIFF(pdata,(*ppdata));
3312                         break;
3313                 }
3314                 case SMB_FILE_INTERNAL_INFORMATION:
3315                         /* This should be an index number - looks like
3316                            dev/ino to me :-) 
3317
3318                            I think this causes us to fail the IFSKIT
3319                            BasicFileInformationTest. -tpot */
3320
3321                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
3322                         SIVAL(pdata,0,sbuf.st_ino); /* FileIndexLow */
3323                         SIVAL(pdata,4,sbuf.st_dev); /* FileIndexHigh */
3324                         data_size = 8;
3325                         break;
3326
3327                 case SMB_FILE_ACCESS_INFORMATION:
3328                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
3329                         SIVAL(pdata,0,access_mask);
3330                         data_size = 4;
3331                         break;
3332
3333                 case SMB_FILE_NAME_INFORMATION:
3334                         /* Pathname with leading '\'. */
3335                         {
3336                                 size_t byte_len;
3337                                 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
3338                                 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
3339                                 SIVAL(pdata,0,byte_len);
3340                                 data_size = 4 + byte_len;
3341                                 break;
3342                         }
3343
3344                 case SMB_FILE_DISPOSITION_INFORMATION:
3345                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
3346                         data_size = 1;
3347                         SCVAL(pdata,0,delete_pending);
3348                         break;
3349
3350                 case SMB_FILE_POSITION_INFORMATION:
3351                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
3352                         data_size = 8;
3353                         SOFF_T(pdata,0,pos);
3354                         break;
3355
3356                 case SMB_FILE_MODE_INFORMATION:
3357                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
3358                         SIVAL(pdata,0,mode);
3359                         data_size = 4;
3360                         break;
3361
3362                 case SMB_FILE_ALIGNMENT_INFORMATION:
3363                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
3364                         SIVAL(pdata,0,0); /* No alignment needed. */
3365                         data_size = 4;
3366                         break;
3367
3368 #if 0
3369                 /*
3370                  * NT4 server just returns "invalid query" to this - if we try to answer
3371                  * it then NTws gets a BSOD! (tridge).
3372                  * W2K seems to want this. JRA.
3373                  */
3374                 case SMB_QUERY_FILE_STREAM_INFO:
3375 #endif
3376                 case SMB_FILE_STREAM_INFORMATION:
3377                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
3378                         if (mode & aDIR) {
3379                                 data_size = 0;
3380                         } else {
3381                                 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", (size_t)0xE, False);
3382                                 SIVAL(pdata,0,0); /* ??? */
3383                                 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
3384                                 SOFF_T(pdata,8,file_size);
3385                                 SIVAL(pdata,16,allocation_size);
3386                                 SIVAL(pdata,20,0); /* ??? */
3387                                 data_size = 24 + byte_len;
3388                         }
3389                         break;
3390
3391                 case SMB_QUERY_COMPRESSION_INFO:
3392                 case SMB_FILE_COMPRESSION_INFORMATION:
3393                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
3394                         SOFF_T(pdata,0,file_size);
3395                         SIVAL(pdata,8,0); /* ??? */
3396                         SIVAL(pdata,12,0); /* ??? */
3397                         data_size = 16;
3398                         break;
3399
3400                 case SMB_FILE_NETWORK_OPEN_INFORMATION:
3401                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
3402                         put_long_date_timespec(pdata,create_time_ts);
3403                         put_long_date_timespec(pdata+8,atime_ts);
3404                         put_long_date_timespec(pdata+16,mtime_ts); /* write time */
3405                         put_long_date_timespec(pdata+24,mtime_ts); /* change time */
3406                         SIVAL(pdata,32,allocation_size);
3407                         SOFF_T(pdata,40,file_size);
3408                         SIVAL(pdata,48,mode);
3409                         SIVAL(pdata,52,0); /* ??? */
3410                         data_size = 56;
3411                         break;
3412
3413                 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
3414                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
3415                         SIVAL(pdata,0,mode);
3416                         SIVAL(pdata,4,0);
3417                         data_size = 8;
3418                         break;
3419
3420                 /*
3421                  * CIFS UNIX Extensions.
3422                  */
3423
3424                 case SMB_QUERY_FILE_UNIX_BASIC:
3425
3426                         DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
3427                         DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
3428
3429                         SOFF_T(pdata,0,get_file_size(sbuf));             /* File size 64 Bit */
3430                         pdata += 8;
3431
3432                         SOFF_T(pdata,0,get_allocation_size(conn,fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
3433                         pdata += 8;
3434
3435                         put_long_date_timespec(pdata,get_ctimespec(&sbuf));       /* Creation Time 64 Bit */
3436                         put_long_date_timespec(pdata+8,get_atimespec(&sbuf));     /* Last access time 64 Bit */
3437                         put_long_date_timespec(pdata+16,get_mtimespec(&sbuf));    /* Last modification time 64 Bit */
3438                         pdata += 24;
3439
3440                         SIVAL(pdata,0,sbuf.st_uid);               /* user id for the owner */
3441                         SIVAL(pdata,4,0);
3442                         pdata += 8;
3443
3444                         SIVAL(pdata,0,sbuf.st_gid);               /* group id of owner */
3445                         SIVAL(pdata,4,0);
3446                         pdata += 8;
3447
3448                         SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
3449                         pdata += 4;
3450
3451                         SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev));   /* Major device number if type is device */
3452                         SIVAL(pdata,4,0);
3453                         pdata += 8;
3454
3455                         SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev));   /* Minor device number if type is device */
3456                         SIVAL(pdata,4,0);
3457                         pdata += 8;
3458
3459                         SINO_T_VAL(pdata,0,(SMB_INO_T)sbuf.st_ino);   /* inode number */
3460                         pdata += 8;
3461                                 
3462                         SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode));     /* Standard UNIX file permissions */
3463                         SIVAL(pdata,4,0);
3464                         pdata += 8;
3465
3466                         SIVAL(pdata,0,sbuf.st_nlink);             /* number of hard links */
3467                         SIVAL(pdata,4,0);
3468                         pdata += 8;
3469                         data_size = PTR_DIFF(pdata,(*ppdata));
3470
3471                         {
3472                                 int i;
3473                                 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
3474
3475                                 for (i=0; i<100; i++)
3476                                         DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
3477                                 DEBUG(4,("\n"));
3478                         }
3479
3480                         break;
3481
3482                 case SMB_QUERY_FILE_UNIX_LINK:
3483                         {
3484                                 pstring buffer;
3485
3486                                 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
3487 #ifdef S_ISLNK
3488                                 if(!S_ISLNK(sbuf.st_mode))
3489                                         return(UNIXERROR(ERRSRV,ERRbadlink));
3490 #else
3491                                 return(UNIXERROR(ERRDOS,ERRbadlink));
3492 #endif
3493                                 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1);     /* read link */
3494                                 if (len == -1)
3495                                         return(UNIXERROR(ERRDOS,ERRnoaccess));
3496                                 buffer[len] = 0;
3497                                 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
3498                                 pdata += len;
3499                                 data_size = PTR_DIFF(pdata,(*ppdata));
3500
3501                                 break;
3502                         }
3503
3504 #if defined(HAVE_POSIX_ACLS)
3505                 case SMB_QUERY_POSIX_ACL:
3506                         {
3507                                 SMB_ACL_T file_acl = NULL;
3508                                 SMB_ACL_T def_acl = NULL;
3509                                 uint16 num_file_acls = 0;
3510                                 uint16 num_def_acls = 0;
3511
3512                                 if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) {
3513                                         file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd);
3514                                 } else {
3515                                         file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
3516                                 }
3517
3518                                 if (file_acl == NULL && no_acl_syscall_error(errno)) {
3519                                         DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
3520                                                 fname ));
3521                                         return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
3522                                 }
3523
3524                                 if (S_ISDIR(sbuf.st_mode)) {
3525                                         if (fsp && fsp->is_directory) {
3526                                                 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
3527                                         } else {
3528                                                 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
3529                                         }
3530                                         def_acl = free_empty_sys_acl(conn, def_acl);
3531                                 }
3532
3533                                 num_file_acls = count_acl_entries(conn, file_acl);
3534                                 num_def_acls = count_acl_entries(conn, def_acl);
3535
3536                                 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
3537                                         DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
3538                                                 data_size,
3539                                                 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
3540                                                         SMB_POSIX_ACL_HEADER_SIZE) ));
3541                                         if (file_acl) {
3542                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3543                                         }
3544                                         if (def_acl) {
3545                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3546                                         }
3547                                         return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
3548                                 }
3549
3550                                 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
3551                                 SSVAL(pdata,2,num_file_acls);
3552                                 SSVAL(pdata,4,num_def_acls);
3553                                 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
3554                                         if (file_acl) {
3555                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3556                                         }
3557                                         if (def_acl) {
3558                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3559                                         }
3560                                         return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3561                                 }
3562                                 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
3563                                         if (file_acl) {
3564                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3565                                         }
3566                                         if (def_acl) {
3567                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3568                                         }
3569                                         return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3570                                 }
3571
3572                                 if (file_acl) {
3573                                         SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3574                                 }
3575                                 if (def_acl) {
3576                                         SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3577                                 }
3578                                 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
3579                                 break;
3580                         }
3581 #endif
3582
3583
3584                 case SMB_QUERY_POSIX_LOCK:
3585                 {
3586                         NTSTATUS status = NT_STATUS_INVALID_LEVEL;
3587                         SMB_BIG_UINT count;
3588                         SMB_BIG_UINT offset;
3589                         uint32 lock_pid;
3590                         enum brl_type lock_type;
3591
3592                         if (total_data != POSIX_LOCK_DATA_SIZE) {
3593                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3594                         }
3595
3596                         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
3597                                 case POSIX_LOCK_TYPE_READ:
3598                                         lock_type = READ_LOCK;
3599                                         break;
3600                                 case POSIX_LOCK_TYPE_WRITE:
3601                                         lock_type = WRITE_LOCK;
3602                                         break;
3603                                 case POSIX_LOCK_TYPE_UNLOCK:
3604                                 default:
3605                                         /* There's no point in asking for an unlock... */
3606                                         talloc_destroy(data_ctx);
3607                                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3608                         }
3609
3610                         lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
3611 #if defined(HAVE_LONGLONG)
3612                         offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
3613                                         ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET));
3614                         count = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
3615                                         ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
3616 #else /* HAVE_LONGLONG */
3617                         offset = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_START_OFFSET);
3618                         count = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
3619 #endif /* HAVE_LONGLONG */
3620
3621                         status = query_lock(fsp,
3622                                         &lock_pid,
3623                                         &count,
3624                                         &offset,
3625                                         &lock_type,
3626                                         POSIX_LOCK);
3627
3628                         if (ERROR_WAS_LOCK_DENIED(status)) {
3629                                 /* Here we need to report who has it locked... */
3630                                 data_size = POSIX_LOCK_DATA_SIZE;
3631
3632                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
3633                                 SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
3634                                 SIVAL(pdata, POSIX_LOCK_PID_OFFSET, lock_pid);
3635 #if defined(HAVE_LONGLONG)
3636                                 SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF));
3637                                 SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF));
3638                                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF));
3639                                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF));
3640 #else /* HAVE_LONGLONG */
3641                                 SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
3642                                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
3643 #endif /* HAVE_LONGLONG */
3644
3645                         } else if (NT_STATUS_IS_OK(status)) {
3646                                 /* For success we just return a copy of what we sent
3647                                    with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
3648                                 data_size = POSIX_LOCK_DATA_SIZE;
3649                                 memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
3650                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
3651                         } else {
3652                                 return ERROR_NT(status);
3653                         }
3654                         break;
3655                 }
3656
3657                 default:
3658                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
3659         }
3660
3661         send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size, max_data_bytes);
3662
3663         return(-1);
3664 }
3665
3666 /****************************************************************************
3667  Set a hard link (called by UNIX extensions and by NT rename with HARD link
3668  code.
3669 ****************************************************************************/
3670
3671 NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname)
3672 {
3673         BOOL bad_path_oldname = False;
3674         BOOL bad_path_newname = False;
3675         SMB_STRUCT_STAT sbuf1, sbuf2;
3676         pstring last_component_oldname;
3677         pstring last_component_newname;
3678         NTSTATUS status = NT_STATUS_OK;
3679
3680         ZERO_STRUCT(sbuf1);
3681         ZERO_STRUCT(sbuf2);
3682
3683         /* No wildcards. */
3684         if (ms_has_wild(newname) || ms_has_wild(oldname)) {
3685                 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
3686         }
3687
3688         unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
3689         if (bad_path_oldname) {
3690                 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3691         }
3692
3693         /* Quick check for "." and ".." */
3694         if (last_component_oldname[0] == '.') {
3695                 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
3696                         return NT_STATUS_OBJECT_NAME_INVALID;
3697                 }
3698         }
3699
3700         /* source must already exist. */
3701         if (!VALID_STAT(sbuf1)) {
3702                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3703         }
3704
3705         if (!check_name(oldname,conn)) {
3706                 return NT_STATUS_ACCESS_DENIED;
3707         }
3708
3709         unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
3710         if (bad_path_newname) {
3711                 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3712         }
3713
3714         /* Quick check for "." and ".." */
3715         if (last_component_newname[0] == '.') {
3716                 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
3717                         return NT_STATUS_OBJECT_NAME_INVALID;
3718                 }
3719         }
3720
3721         /* Disallow if newname already exists. */
3722         if (VALID_STAT(sbuf2)) {
3723                 return NT_STATUS_OBJECT_NAME_COLLISION;
3724         }
3725
3726         if (!check_name(newname,conn)) {
3727                 return NT_STATUS_ACCESS_DENIED;
3728         }
3729
3730         /* No links from a directory. */
3731         if (S_ISDIR(sbuf1.st_mode)) {
3732                 return NT_STATUS_FILE_IS_A_DIRECTORY;
3733         }
3734
3735         /* Ensure this is within the share. */
3736         if (!reduce_name(conn, oldname) != 0)
3737                 return NT_STATUS_ACCESS_DENIED;
3738
3739         DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
3740
3741         if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
3742                 status = map_nt_error_from_unix(errno);
3743                 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3744                                 nt_errstr(status), newname, oldname));
3745         }
3746
3747         return status;
3748 }
3749
3750 /****************************************************************************
3751  Reply to a TRANS2_SETFILEINFO (set file info by fileid).
3752 ****************************************************************************/
3753
3754 static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3755                                         unsigned int tran_call,
3756                                         char **pparams, int total_params, char **ppdata, int total_data,
3757                                         unsigned int max_data_bytes)
3758 {
3759         char *params = *pparams;
3760         char *pdata = *ppdata;
3761         uint16 info_level;
3762         int dosmode=0;
3763         SMB_OFF_T size=0;
3764         struct utimbuf tvs;
3765         SMB_STRUCT_STAT sbuf;
3766         pstring fname;
3767         int fd = -1;
3768         BOOL bad_path = False;
3769         files_struct *fsp = NULL;
3770         uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
3771         gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
3772         mode_t unixmode = 0;
3773         NTSTATUS status = NT_STATUS_OK;
3774
3775         if (!params)
3776                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3777
3778         ZERO_STRUCT(sbuf);
3779         ZERO_STRUCT(tvs);
3780
3781         if (tran_call == TRANSACT2_SETFILEINFO) {
3782                 if (total_params < 4) {
3783                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3784                 }
3785
3786                 fsp = file_fsp(params,0);
3787                 info_level = SVAL(params,2);    
3788
3789                 if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
3790                         /*
3791                          * This is actually a SETFILEINFO on a directory
3792                          * handle (returned from an NT SMB). NT5.0 seems
3793                          * to do this call. JRA.
3794                          */
3795                         pstrcpy(fname, fsp->fsp_name);
3796                         if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) {
3797                                 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
3798                                 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3799                         }
3800                 } else if (fsp && fsp->print_file) {
3801                         /*
3802                          * Doing a DELETE_ON_CLOSE should cancel a print job.
3803                          */
3804                         if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
3805                                 fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
3806
3807                                 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
3808         
3809                                 SSVAL(params,0,0);
3810                                 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
3811                                 return(-1);
3812                         } else
3813                                 return (UNIXERROR(ERRDOS,ERRbadpath));
3814             } else {
3815                         /*
3816                          * Original code - this is an open file.
3817                          */
3818                         CHECK_FSP(fsp,conn);
3819
3820                         pstrcpy(fname, fsp->fsp_name);
3821                         fd = fsp->fh->fd;
3822
3823                         if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
3824                                 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
3825                                 return(UNIXERROR(ERRDOS,ERRbadfid));
3826                         }
3827                 }
3828         } else {
3829                 /* set path info */
3830                 if (total_params < 6) {
3831                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3832                 }
3833
3834                 info_level = SVAL(params,0);    
3835                 srvstr_get_path(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE, &status);
3836                 if (!NT_STATUS_IS_OK(status)) {
3837                         return ERROR_NT(status);
3838                 }
3839                 unix_convert(fname,conn,0,&bad_path,&sbuf);
3840                 if (bad_path) {
3841                         return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3842                 }
3843
3844                 /*
3845                  * For CIFS UNIX extensions the target name may not exist.
3846                  */
3847
3848                 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
3849                         DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
3850                         return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3851                 }    
3852
3853                 if(!check_name(fname, conn)) {
3854                         return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3855                 }
3856
3857         }
3858
3859         if (!CAN_WRITE(conn))
3860                 return ERROR_DOS(ERRSRV,ERRaccess);
3861
3862         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
3863                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
3864         }
3865
3866         if (VALID_STAT(sbuf))
3867                 unixmode = sbuf.st_mode;
3868
3869         DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3870                 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
3871
3872         /* Realloc the parameter size */
3873         *pparams = (char *)SMB_REALLOC(*pparams,2);
3874         if (*pparams == NULL) {
3875                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3876         }
3877         params = *pparams;
3878
3879         SSVAL(params,0,0);
3880
3881         if (fsp && fsp->pending_modtime) {
3882                 /* the pending modtime overrides the current modtime */
3883                 sbuf.st_mtime = fsp->pending_modtime;
3884         }
3885
3886         size = get_file_size(sbuf);
3887         tvs.modtime = sbuf.st_mtime;
3888         tvs.actime = sbuf.st_atime;
3889         dosmode = dos_mode(conn,fname,&sbuf);
3890         unixmode = sbuf.st_mode;
3891
3892         set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
3893         set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
3894
3895         switch (info_level) {
3896                 case SMB_INFO_STANDARD:
3897                 {
3898                         if (total_data < 12) {
3899                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3900                         }
3901
3902                         /* access time */
3903                         tvs.actime = srv_make_unix_date2(pdata+l1_fdateLastAccess);
3904                         /* write time */
3905                         tvs.modtime = srv_make_unix_date2(pdata+l1_fdateLastWrite);
3906                         break;
3907                 }
3908
3909                 case SMB_INFO_SET_EA:
3910                 {
3911                         struct ea_list *ea_list = NULL;
3912                         TALLOC_CTX *ctx = NULL;
3913
3914                         if (total_data < 10) {
3915
3916                                 /* OS/2 workplace shell seems to send SET_EA requests of "null"
3917                                    length. They seem to have no effect. Bug #3212. JRA */
3918
3919                                 if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
3920                                         /* We're done. We only get EA info in this call. */
3921                                         SSVAL(params,0,0);
3922                                         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
3923                                         return(-1);
3924                                 }
3925
3926                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3927                         }
3928
3929                         if (IVAL(pdata,0) > total_data) {
3930                                 DEBUG(10,("call_trans2setfilepathinfo: bad total data size (%u) > %u\n",
3931                                         IVAL(pdata,0), (unsigned int)total_data));
3932                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3933                         }
3934
3935                         ctx = talloc_init("SMB_INFO_SET_EA");
3936                         if (!ctx) {
3937                                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3938                         }
3939                         ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
3940                         if (!ea_list) {
3941                                 talloc_destroy(ctx);
3942                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3943                         }
3944                         status = set_ea(conn, fsp, fname, ea_list);
3945                         talloc_destroy(ctx);
3946
3947                         if (!NT_STATUS_IS_OK(status)) {
3948                                 return ERROR_NT(status);
3949                         }
3950
3951                         /* We're done. We only get EA info in this call. */
3952                         SSVAL(params,0,0);
3953                         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
3954                         return(-1);
3955                 }
3956
3957 #if 0
3958                 /* The following 2 info levels are only valid on query, not set. Remove them. JRA. */
3959                 /* XXXX um, i don't think this is right.
3960                         it's also not in the cifs6.txt spec.
3961                 */
3962                 case SMB_INFO_QUERY_EAS_FROM_LIST:
3963                         if (total_data < 28)
3964                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3965
3966                         tvs.actime = make_unix_date2(pdata+8);
3967                         tvs.modtime = make_unix_date2(pdata+12);
3968                         size = IVAL(pdata,16);
3969                         dosmode = IVAL(pdata,24);
3970                         break;
3971
3972                 /* XXXX nor this.  not in cifs6.txt, either. */
3973                 case SMB_INFO_QUERY_ALL_EAS:
3974                         if (total_data < 28)
3975                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3976
3977                         tvs.actime = make_unix_date2(pdata+8);
3978                         tvs.modtime = make_unix_date2(pdata+12);
3979                         size = IVAL(pdata,16);
3980                         dosmode = IVAL(pdata,24);
3981                         break;
3982 #endif
3983
3984                 case SMB_SET_FILE_BASIC_INFO:
3985                 case SMB_FILE_BASIC_INFORMATION:
3986                 {
3987                         /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3988                         time_t write_time;
3989                         time_t changed_time;
3990
3991                         if (total_data < 36) {
3992                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3993                         }
3994
3995                         /* Ignore create time at offset pdata. */
3996
3997                         /* access time */
3998                         tvs.actime = convert_timespec_to_time_t(interpret_long_date(pdata+8));
3999
4000                         write_time = convert_timespec_to_time_t(interpret_long_date(pdata+16));
4001                         changed_time = convert_timespec_to_time_t(interpret_long_date(pdata+24));
4002
4003                         tvs.modtime = MIN(write_time, changed_time);
4004
4005                         if (write_time > tvs.modtime && write_time != (time_t)-1) {
4006                                 tvs.modtime = write_time;
4007                         }
4008                         /* Prefer a defined time to an undefined one. */
4009                         if (null_mtime(tvs.modtime)) {
4010                                 tvs.modtime = null_mtime(write_time) ? changed_time : write_time;
4011                         }
4012
4013                         /* attributes */
4014                         dosmode = IVAL(pdata,32);
4015                         break;
4016                 }
4017
4018                 case SMB_FILE_ALLOCATION_INFORMATION:
4019                 case SMB_SET_FILE_ALLOCATION_INFO:
4020                 {
4021                         int ret = -1;
4022                         SMB_BIG_UINT allocation_size;
4023
4024                         if (total_data < 8) {
4025                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4026                         }
4027
4028                         allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
4029 #ifdef LARGE_SMB_OFF_T
4030                         allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
4031 #else /* LARGE_SMB_OFF_T */
4032                         if (IVAL(pdata,4) != 0) {
4033                                 /* more than 32 bits? */
4034                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4035                         }
4036 #endif /* LARGE_SMB_OFF_T */
4037                         DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
4038                                         fname, (double)allocation_size ));
4039
4040                         if (allocation_size) {
4041                                 allocation_size = smb_roundup(conn, allocation_size);
4042                         }
4043
4044                         if(allocation_size != get_file_size(sbuf)) {
4045                                 SMB_STRUCT_STAT new_sbuf;
4046  
4047                                 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
4048                                         fname, (double)allocation_size ));
4049  
4050                                 if (fd == -1) {
4051                                         files_struct *new_fsp = NULL;
4052  
4053                                         status = open_file_ntcreate(conn, fname, &sbuf,
4054                                                                         FILE_WRITE_DATA,
4055                                                                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4056                                                                         FILE_OPEN,
4057                                                                         0,
4058                                                                         FILE_ATTRIBUTE_NORMAL,
4059                                                                         FORCE_OPLOCK_BREAK_TO_NONE,
4060                                                                         NULL, &new_fsp);
4061  
4062                                         if (!NT_STATUS_IS_OK(status)) {
4063                                                 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
4064                                                         /* We have re-scheduled this call. */
4065                                                         return -1;
4066                                                 }
4067                                                 return(UNIXERROR(ERRDOS,ERRnoaccess));
4068                                         }
4069                                         ret = vfs_allocate_file_space(new_fsp, allocation_size);
4070                                         if (SMB_VFS_FSTAT(new_fsp,new_fsp->fh->fd,&new_sbuf) != 0) {
4071                                                 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
4072                                                                         new_fsp->fnum, strerror(errno)));
4073                                                 ret = -1;
4074                                         }
4075                                         close_file(new_fsp,NORMAL_CLOSE);
4076                                 } else {
4077                                         ret = vfs_allocate_file_space(fsp, allocation_size);
4078                                         if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
4079                                                 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
4080                                                                         fsp->fnum, strerror(errno)));
4081                                                 ret = -1;
4082                                         }
4083                                 }
4084                                 if (ret == -1)
4085                                         return ERROR_NT(NT_STATUS_DISK_FULL);
4086
4087                                 /* Allocate can truncate size... */
4088                                 size = get_file_size(new_sbuf);
4089                         }
4090
4091                         break;
4092                 }
4093
4094                 case SMB_FILE_END_OF_FILE_INFORMATION:
4095                 case SMB_SET_FILE_END_OF_FILE_INFO:
4096                 {
4097                         if (total_data < 8) {
4098                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4099                         }
4100
4101                         size = IVAL(pdata,0);
4102 #ifdef LARGE_SMB_OFF_T
4103                         size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
4104 #else /* LARGE_SMB_OFF_T */
4105                         if (IVAL(pdata,4) != 0) {
4106                                 /* more than 32 bits? */
4107                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4108                         }
4109 #endif /* LARGE_SMB_OFF_T */
4110                         DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
4111                         break;
4112                 }
4113
4114                 case SMB_FILE_DISPOSITION_INFORMATION:
4115                 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
4116                 {
4117                         BOOL delete_on_close;
4118
4119                         if (total_data < 1) {
4120                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4121                         }
4122
4123                         delete_on_close = (CVAL(pdata,0) ? True : False);
4124
4125                         /* Just ignore this set on a path. */
4126                         if (tran_call != TRANSACT2_SETFILEINFO)
4127                                 break;
4128
4129                         if (fsp == NULL)
4130                                 return(UNIXERROR(ERRDOS,ERRbadfid));
4131
4132                         status = can_set_delete_on_close(fsp, delete_on_close,
4133                                                          dosmode);
4134  
4135                         if (!NT_STATUS_IS_OK(status)) {
4136                                 return ERROR_NT(status);
4137                         }
4138
4139                         /* The set is across all open files on this dev/inode pair. */
4140                         if (!set_delete_on_close(fsp, delete_on_close, &current_user.ut)) {
4141                                 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
4142                         }
4143
4144                         SSVAL(params,0,0);
4145                         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4146                         return(-1);
4147                 }
4148
4149                 case SMB_FILE_POSITION_INFORMATION:
4150                 {
4151                         SMB_BIG_UINT position_information;
4152
4153                         if (total_data < 8) {
4154                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4155                         }
4156
4157                         position_information = (SMB_BIG_UINT)IVAL(pdata,0);
4158 #ifdef LARGE_SMB_OFF_T
4159                         position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
4160 #else /* LARGE_SMB_OFF_T */
4161                         if (IVAL(pdata,4) != 0) {
4162                                 /* more than 32 bits? */
4163                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4164                         }
4165 #endif /* LARGE_SMB_OFF_T */
4166                         DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
4167                                         fname, (double)position_information ));
4168                         if (fsp) {
4169                                 fsp->fh->position_information = position_information;
4170                         }
4171
4172                         /* We're done. We only get position info in this call. */
4173                         SSVAL(params,0,0);
4174                         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4175                         return(-1);
4176                 }
4177
4178                 /* From tridge Samba4 : 
4179                  * MODE_INFORMATION in setfileinfo (I have no
4180                  * idea what "mode information" on a file is - it takes a value of 0,
4181                  * 2, 4 or 6. What could it be?).
4182                  */
4183
4184                 case SMB_FILE_MODE_INFORMATION:
4185                 {
4186                         uint32 mode;
4187
4188                         if (total_data < 4) {
4189                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4190                         }
4191                         mode = IVAL(pdata,0);
4192                         if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
4193                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4194                         }
4195
4196                         /* We're done. We only get mode info in this call. */
4197                         SSVAL(params,0,0);
4198                         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4199                         return(-1);
4200                 }
4201
4202                 /*
4203                  * CIFS UNIX extensions.
4204                  */
4205
4206                 case SMB_SET_FILE_UNIX_BASIC:
4207                 {
4208                         uint32 raw_unixmode;
4209
4210                         if (total_data < 100) {
4211                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4212                         }
4213
4214                         if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
4215                            IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
4216                                 size=IVAL(pdata,0); /* first 8 Bytes are size */
4217 #ifdef LARGE_SMB_OFF_T
4218                                 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
4219 #else /* LARGE_SMB_OFF_T */
4220                                 if (IVAL(pdata,4) != 0) {
4221                                         /* more than 32 bits? */
4222                                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4223                                 }
4224 #endif /* LARGE_SMB_OFF_T */
4225                         }
4226                         pdata+=24;          /* ctime & st_blocks are not changed */
4227                         tvs.actime = convert_timespec_to_time_t(interpret_long_date(pdata)); /* access_time */
4228                         tvs.modtime = convert_timespec_to_time_t(interpret_long_date(pdata+8)); /* modification_time */
4229                         pdata+=16;
4230                         set_owner = (uid_t)IVAL(pdata,0);
4231                         pdata += 8;
4232                         set_grp = (gid_t)IVAL(pdata,0);
4233                         pdata += 8;
4234                         raw_unixmode = IVAL(pdata,28);
4235                         unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
4236                         dosmode = 0; /* Ensure dos mode change doesn't override this. */
4237
4238                         DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
4239 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
4240                                 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
4241
4242                         if (!VALID_STAT(sbuf)) {
4243
4244                                 /*
4245                                  * The only valid use of this is to create character and block
4246                                  * devices, and named pipes. This is deprecated (IMHO) and 
4247                                  * a new info level should be used for mknod. JRA.
4248                                  */
4249
4250                                 uint32 file_type = IVAL(pdata,0);
4251 #if defined(HAVE_MAKEDEV)
4252                                 uint32 dev_major = IVAL(pdata,4);
4253                                 uint32 dev_minor = IVAL(pdata,12);
4254 #endif
4255
4256                                 uid_t myuid = geteuid();
4257                                 gid_t mygid = getegid();
4258                                 SMB_DEV_T dev = (SMB_DEV_T)0;
4259
4260                                 if (tran_call == TRANSACT2_SETFILEINFO)
4261                                         return(ERROR_DOS(ERRDOS,ERRnoaccess));
4262
4263                                 if (raw_unixmode == SMB_MODE_NO_CHANGE) {
4264                                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4265                                 }
4266
4267 #if defined(HAVE_MAKEDEV)
4268                                 dev = makedev(dev_major, dev_minor);
4269 #endif
4270
4271                                 /* We can only create as the owner/group we are. */
4272
4273                                 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
4274                                         return(ERROR_DOS(ERRDOS,ERRnoaccess));
4275                                 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
4276                                         return(ERROR_DOS(ERRDOS,ERRnoaccess));
4277
4278                                 switch (file_type) {
4279 #if defined(S_IFIFO)
4280                                         case UNIX_TYPE_FIFO:
4281                                                 unixmode |= S_IFIFO;
4282                                                 break;
4283 #endif
4284 #if defined(S_IFSOCK)
4285                                         case UNIX_TYPE_SOCKET:
4286                                                 unixmode |= S_IFSOCK;
4287                                                 break;
4288 #endif
4289 #if defined(S_IFCHR)
4290                                         case UNIX_TYPE_CHARDEV:
4291                                                 unixmode |= S_IFCHR;
4292                                                 break;
4293 #endif
4294 #if defined(S_IFBLK)
4295                                         case UNIX_TYPE_BLKDEV:
4296                                                 unixmode |= S_IFBLK;
4297                                                 break;
4298 #endif
4299                                         default:
4300                                                 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4301                                 }
4302
4303                                 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
4304 0%o for file %s\n", (double)dev, unixmode, fname ));
4305
4306                                 /* Ok - do the mknod. */
4307                                 if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0)
4308                                         return(UNIXERROR(ERRDOS,ERRnoaccess));
4309
4310                                 if (lp_inherit_perms(SNUM(conn))) {
4311                                         inherit_access_acl(conn, fname,
4312                                                            unixmode);
4313                                 }
4314
4315                                 SSVAL(params,0,0);
4316                                 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4317                                 return(-1);
4318                         }
4319
4320                         /*
4321                          * Deal with the UNIX specific mode set.
4322                          */
4323
4324                         if (raw_unixmode != SMB_MODE_NO_CHANGE) {
4325                                 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
4326                                         (unsigned int)unixmode, fname ));
4327                                 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
4328                                         return(UNIXERROR(ERRDOS,ERRnoaccess));
4329                         }
4330
4331                         /*
4332                          * Deal with the UNIX specific uid set.
4333                          */
4334
4335                         if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
4336                                 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
4337                                         (unsigned int)set_owner, fname ));
4338                                 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
4339                                         return(UNIXERROR(ERRDOS,ERRnoaccess));
4340                         }
4341
4342                         /*
4343                          * Deal with the UNIX specific gid set.
4344                          */
4345
4346                         if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
4347                                 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
4348                                         (unsigned int)set_owner, fname ));
4349                                 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
4350                                         return(UNIXERROR(ERRDOS,ERRnoaccess));
4351                         }
4352                         break;
4353                 }
4354
4355                 case SMB_SET_FILE_UNIX_LINK:
4356                 {
4357                         pstring link_target;
4358                         char *newname = fname;
4359
4360                         /* Set a symbolic link. */
4361                         /* Don't allow this if follow links is false. */
4362
4363                         if (!lp_symlinks(SNUM(conn)))
4364                                 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4365
4366                         srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE);
4367
4368                         /* !widelinks forces the target path to be within the share. */
4369                         /* This means we can interpret the target as a pathname. */
4370                         if (!lp_widelinks(SNUM(conn))) {
4371                                 pstring rel_name;
4372                                 char *last_dirp = NULL;
4373
4374                                 unix_format(link_target);
4375                                 if (*link_target == '/') {
4376                                         /* No absolute paths allowed. */
4377                                         return(UNIXERROR(ERRDOS,ERRnoaccess));
4378                                 }
4379                                 pstrcpy(rel_name, newname);
4380                                 last_dirp = strrchr_m(rel_name, '/');
4381                                 if (last_dirp) {
4382                                         last_dirp[1] = '\0';
4383                                 } else {
4384                                         pstrcpy(rel_name, "./");
4385                                 }
4386                                 pstrcat(rel_name, link_target);
4387
4388                                 if (!check_name(rel_name, conn)) {
4389                                         return(UNIXERROR(ERRDOS,ERRnoaccess));
4390                                 }
4391                         }
4392
4393                         DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
4394                                 fname, link_target ));
4395
4396                         if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
4397                                 return(UNIXERROR(ERRDOS,ERRnoaccess));
4398                         SSVAL(params,0,0);
4399                         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4400                         return(-1);
4401                 }
4402
4403                 case SMB_SET_FILE_UNIX_HLINK:
4404                 {
4405                         pstring oldname;
4406                         char *newname = fname;
4407
4408                         /* Set a hard link. */
4409                         srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status);
4410                         if (!NT_STATUS_IS_OK(status)) {
4411                                 return ERROR_NT(status);
4412                         }
4413
4414                         DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
4415                                 fname, oldname));
4416
4417                         status = hardlink_internals(conn, oldname, newname);
4418                         if (!NT_STATUS_IS_OK(status)) {
4419                                 return ERROR_NT(status);
4420                         }
4421
4422                         SSVAL(params,0,0);
4423                         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4424                         return(-1);
4425                 }
4426
4427                 case SMB_FILE_RENAME_INFORMATION:
4428                 {
4429                         BOOL overwrite;
4430                         /* uint32 root_fid; */  /* Not used */
4431                         uint32 len;
4432                         pstring newname;
4433                         pstring base_name;
4434                         char *p;
4435
4436                         if (total_data < 12) {
4437                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4438                         }
4439
4440                         overwrite = (CVAL(pdata,0) ? True : False);
4441                         /* root_fid = IVAL(pdata,4); */
4442                         len = IVAL(pdata,8);
4443                         srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status);
4444                         if (!NT_STATUS_IS_OK(status)) {
4445                                 return ERROR_NT(status);
4446                         }
4447
4448                         /* Check the new name has no '/' characters. */
4449                         if (strchr_m(newname, '/'))
4450                                 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
4451
4452                         RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
4453
4454                         /* Create the base directory. */
4455                         pstrcpy(base_name, fname);
4456                         p = strrchr_m(base_name, '/');
4457                         if (p)
4458                                 *p = '\0';
4459                         /* Append the new name. */
4460                         pstrcat(base_name, "/");
4461                         pstrcat(base_name, newname);
4462
4463                         if (fsp) {
4464                                 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
4465                                         fsp->fnum, fsp->fsp_name, base_name ));
4466                                 status = rename_internals_fsp(conn, fsp, base_name, 0, overwrite);
4467                         } else {
4468                                 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
4469                                         fname, newname ));
4470                                 status = rename_internals(conn, fname, base_name, 0, overwrite, False);
4471                         }
4472                         if (!NT_STATUS_IS_OK(status)) {
4473                                 return ERROR_NT(status);
4474                         }
4475                         process_pending_change_notify_queue((time_t)0);
4476                         SSVAL(params,0,0);
4477                         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4478                         return(-1);
4479                 }
4480
4481 #if defined(HAVE_POSIX_ACLS)
4482                 case SMB_SET_POSIX_ACL:
4483                 {
4484                         uint16 posix_acl_version;
4485                         uint16 num_file_acls;
4486                         uint16 num_def_acls;
4487                         BOOL valid_file_acls = True;
4488                         BOOL valid_def_acls = True;
4489
4490                         if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
4491                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4492                         }
4493                         posix_acl_version = SVAL(pdata,0);
4494                         num_file_acls = SVAL(pdata,2);
4495                         num_def_acls = SVAL(pdata,4);
4496
4497                         if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4498                                 valid_file_acls = False;
4499                                 num_file_acls = 0;
4500                         }
4501
4502                         if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4503                                 valid_def_acls = False;
4504                                 num_def_acls = 0;
4505                         }
4506
4507                         if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
4508                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4509                         }
4510
4511                         if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
4512                                         (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
4513                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4514                         }
4515
4516                         if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
4517                                         pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
4518                                 return(UNIXERROR(ERRDOS,ERRnoaccess));
4519                         }
4520
4521                         if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, &sbuf, num_def_acls,
4522                                         pdata + SMB_POSIX_ACL_HEADER_SIZE +
4523                                         (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
4524                                 return(UNIXERROR(ERRDOS,ERRnoaccess));
4525                         }
4526
4527                         SSVAL(params,0,0);
4528                         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4529                         return(-1);
4530                 }
4531 #endif
4532
4533                 case SMB_SET_POSIX_LOCK:
4534                 {
4535                         SMB_BIG_UINT count;
4536                         SMB_BIG_UINT offset;
4537                         uint32 lock_pid;
4538                         BOOL blocking_lock = False;
4539                         enum brl_type lock_type;
4540
4541                         if (fsp == NULL || fsp->fh->fd == -1) {
4542                                 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
4543                         }
4544
4545                         if (total_data != POSIX_LOCK_DATA_SIZE) {
4546                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4547                         }
4548
4549                         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
4550                                 case POSIX_LOCK_TYPE_READ:
4551                                         lock_type = READ_LOCK;
4552                                         break;
4553                                 case POSIX_LOCK_TYPE_WRITE:
4554                                         /* Return the right POSIX-mappable error code for files opened read-only. */
4555                                         if (!fsp->can_write) {
4556                                                 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
4557                                         }
4558                                         lock_type = WRITE_LOCK;
4559                                         break;
4560                                 case POSIX_LOCK_TYPE_UNLOCK:
4561                                         lock_type = UNLOCK_LOCK;
4562                                         break;
4563                                 default:
4564                                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4565                         }
4566
4567                         if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_NOWAIT) {
4568                                 blocking_lock = False;
4569                         } else if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_WAIT) {
4570                                 blocking_lock = True;
4571                         } else {
4572                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4573                         }
4574
4575                         if (!lp_blocking_locks(SNUM(conn))) { 
4576                                 blocking_lock = False;
4577                         }
4578
4579                         lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
4580 #if defined(HAVE_LONGLONG)
4581                         offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
4582                                         ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET));
4583                         count = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
4584                                         ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
4585 #else /* HAVE_LONGLONG */
4586                         offset = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_START_OFFSET);
4587                         count = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
4588 #endif /* HAVE_LONGLONG */
4589
4590                         if (lock_type == UNLOCK_LOCK) {
4591                                 status = do_unlock(fsp,
4592                                                 lock_pid,
4593                                                 count,
4594                                                 offset,
4595                                                 POSIX_LOCK);
4596                         } else {
4597                                 struct byte_range_lock *br_lck = do_lock(fsp,
4598                                                                         lock_pid,
4599                                                                         count,
4600                                                                         offset,
4601                                                                         lock_type,
4602                                                                         POSIX_LOCK,
4603                                                                         blocking_lock,
4604                                                                         &status);
4605
4606                                 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
4607                                         /*
4608                                          * A blocking lock was requested. Package up
4609                                          * this smb into a queued request and push it
4610                                          * onto the blocking lock queue.
4611                                          */
4612                                         if(push_blocking_lock_request(br_lck,
4613                                                                 inbuf, length,
4614                                                                 fsp,
4615                                                                 -1, /* infinite timeout. */
4616                                                                 0,
4617                                                                 lock_pid,
4618                                                                 lock_type,
4619                                                                 POSIX_LOCK,
4620                                                                 offset,
4621                                                                 count)) {
4622                                                 TALLOC_FREE(br_lck);
4623                                                 return -1;
4624                                         }
4625                                 }
4626                                 TALLOC_FREE(br_lck);
4627                         }
4628
4629                         if (!NT_STATUS_IS_OK(status)) {
4630                                 return ERROR_NT(status);
4631                         }
4632
4633                         SSVAL(params,0,0);
4634                         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4635                         return(-1);
4636                 }
4637
4638                 default:
4639                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
4640         }
4641
4642         /* get some defaults (no modifications) if any info is zero or -1. */
4643         if (null_mtime(tvs.actime)) {
4644                 tvs.actime = sbuf.st_atime;
4645         }
4646
4647         if (null_mtime(tvs.modtime)) {
4648                 tvs.modtime = sbuf.st_mtime;
4649         }
4650
4651         DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
4652         DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
4653         DEBUG(6,("size: %.0f ", (double)size));
4654
4655         if (dosmode) {
4656                 if (S_ISDIR(sbuf.st_mode))
4657                         dosmode |= aDIR;
4658                 else
4659                         dosmode &= ~aDIR;
4660         }
4661
4662         DEBUG(6,("dosmode: %x\n"  , dosmode));
4663
4664         if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
4665                 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
4666                 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
4667                 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
4668
4669                 /*
4670                  * Only do this test if we are not explicitly
4671                  * changing the size of a file.
4672                  */
4673                 if (!size)
4674                         size = get_file_size(sbuf);
4675         }
4676
4677         /*
4678          * Try and set the times, size and mode of this file -
4679          * if they are different from the current values
4680          */
4681
4682         /* check the mode isn't different, before changing it */
4683         if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
4684
4685                 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
4686
4687                 if(file_set_dosmode(conn, fname, dosmode, &sbuf, False)) {
4688                         DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
4689                         return(UNIXERROR(ERRDOS,ERRnoaccess));
4690                 }
4691         }
4692
4693         /* Now the size. */
4694         if (size != get_file_size(sbuf)) {
4695
4696                 int ret;
4697
4698                 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
4699                         fname, (double)size ));
4700
4701                 if (fd == -1) {
4702                         files_struct *new_fsp = NULL;
4703
4704                         status = open_file_ntcreate(conn, fname, &sbuf,
4705                                                 FILE_WRITE_DATA,
4706                                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4707                                                 FILE_OPEN,
4708                                                 0,
4709                                                 FILE_ATTRIBUTE_NORMAL,
4710                                                 FORCE_OPLOCK_BREAK_TO_NONE,
4711                                                 NULL, &new_fsp);
4712         
4713                         if (!NT_STATUS_IS_OK(status)) {
4714                                 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
4715                                         /* We have re-scheduled this call. */
4716                                         return -1;
4717                                 }
4718                                 return(UNIXERROR(ERRDOS,ERRnoaccess));
4719                         }
4720                         ret = vfs_set_filelen(new_fsp, size);
4721                         close_file(new_fsp,NORMAL_CLOSE);
4722                 } else {
4723                         ret = vfs_set_filelen(fsp, size);
4724                 }
4725
4726                 if (ret == -1) {
4727                         return (UNIXERROR(ERRHRD,ERRdiskfull));
4728                 }
4729         }
4730
4731         /*
4732          * Finally the times.
4733          */
4734         if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
4735                 if(fsp != NULL) {
4736                         /*
4737                          * This was a setfileinfo on an open file.
4738                          * NT does this a lot. We also need to 
4739                          * set the time here, as it can be read by 
4740                          * FindFirst/FindNext and with the patch for bug #2045
4741                          * in smbd/fileio.c it ensures that this timestamp is
4742                          * kept sticky even after a write. We save the request
4743                          * away and will set it on file close and after a write. JRA.
4744                          */
4745
4746                         if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
4747                                 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
4748                                 fsp_set_pending_modtime(fsp, tvs.modtime);
4749                         }
4750
4751                 }
4752                 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
4753
4754                 if(file_utime(conn, fname, &tvs)!=0) {
4755                         return(UNIXERROR(ERRDOS,ERRnoaccess));
4756                 }
4757         }
4758
4759         SSVAL(params,0,0);
4760         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4761   
4762         return(-1);
4763 }
4764
4765 /****************************************************************************
4766  Reply to a TRANS2_MKDIR (make directory with extended attributes).
4767 ****************************************************************************/
4768
4769 static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4770                                         char **pparams, int total_params, char **ppdata, int total_data,
4771                                         unsigned int max_data_bytes)
4772 {
4773         char *params = *pparams;
4774         char *pdata = *ppdata;
4775         pstring directory;
4776         int ret = -1;
4777         SMB_STRUCT_STAT sbuf;
4778         BOOL bad_path = False;
4779         NTSTATUS status = NT_STATUS_OK;
4780         TALLOC_CTX *ctx = NULL;
4781         struct ea_list *ea_list = NULL;
4782
4783         if (!CAN_WRITE(conn))
4784                 return ERROR_DOS(ERRSRV,ERRaccess);
4785
4786         if (total_params < 4) {
4787                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4788         }
4789
4790         srvstr_get_path(inbuf, directory, &params[4], sizeof(directory), -1, STR_TERMINATE, &status);
4791         if (!NT_STATUS_IS_OK(status)) {
4792                 return ERROR_NT(status);
4793         }
4794
4795         DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
4796
4797         unix_convert(directory,conn,0,&bad_path,&sbuf);
4798         if (bad_path) {
4799                 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
4800         }
4801
4802         /* Any data in this call is an EA list. */
4803         if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
4804                 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
4805         }
4806
4807         /*
4808          * OS/2 workplace shell seems to send SET_EA requests of "null"
4809          * length (4 bytes containing IVAL 4).
4810          * They seem to have no effect. Bug #3212. JRA.
4811          */
4812
4813         if (total_data != 4) {
4814                 if (total_data < 10) {
4815                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4816                 }
4817
4818                 if (IVAL(pdata,0) > total_data) {
4819                         DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
4820                                 IVAL(pdata,0), (unsigned int)total_data));
4821                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4822                 }
4823
4824                 ctx = talloc_init("TRANS2_MKDIR_SET_EA");
4825                 if (!ctx) {
4826                         return ERROR_NT(NT_STATUS_NO_MEMORY);
4827                 }
4828                 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
4829                 if (!ea_list) {
4830                         talloc_destroy(ctx);
4831                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4832                 }
4833         } else if (IVAL(pdata,0) != 4) {
4834                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4835         }
4836
4837         if (check_name(directory,conn)) {
4838                 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
4839         }
4840   
4841         if(ret < 0) {
4842                 talloc_destroy(ctx);
4843                 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
4844                 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
4845         }
4846
4847         /* Try and set any given EA. */
4848         if (total_data) {
4849                 status = set_ea(conn, NULL, directory, ea_list);
4850                 talloc_destroy(ctx);
4851                 if (!NT_STATUS_IS_OK(status)) {
4852                         return ERROR_NT(status);
4853                 }
4854         }
4855
4856         /* Realloc the parameter and data sizes */
4857         *pparams = (char *)SMB_REALLOC(*pparams,2);
4858         if(*pparams == NULL) {
4859                 return ERROR_NT(NT_STATUS_NO_MEMORY);
4860         }
4861         params = *pparams;
4862
4863         SSVAL(params,0,0);
4864
4865         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4866   
4867         return(-1);
4868 }
4869
4870 /****************************************************************************
4871  Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
4872  We don't actually do this - we just send a null response.
4873 ****************************************************************************/
4874
4875 static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4876                                         char **pparams, int total_params, char **ppdata, int total_data,
4877                                         unsigned int max_data_bytes)
4878 {
4879         static uint16 fnf_handle = 257;
4880         char *params = *pparams;
4881         uint16 info_level;
4882
4883         if (total_params < 6) {
4884                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4885         }
4886
4887         info_level = SVAL(params,4);
4888         DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
4889
4890         switch (info_level) {
4891                 case 1:
4892                 case 2:
4893                         break;
4894                 default:
4895                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
4896         }
4897
4898         /* Realloc the parameter and data sizes */
4899         *pparams = (char *)SMB_REALLOC(*pparams,6);
4900         if (*pparams == NULL) {
4901                 return ERROR_NT(NT_STATUS_NO_MEMORY);
4902         }
4903         params = *pparams;
4904
4905         SSVAL(params,0,fnf_handle);
4906         SSVAL(params,2,0); /* No changes */
4907         SSVAL(params,4,0); /* No EA errors */
4908
4909         fnf_handle++;
4910
4911         if(fnf_handle == 0)
4912                 fnf_handle = 257;
4913
4914         send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0, max_data_bytes);
4915   
4916         return(-1);
4917 }
4918
4919 /****************************************************************************
4920  Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for 
4921  changes). Currently this does nothing.
4922 ****************************************************************************/
4923
4924 static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4925                                         char **pparams, int total_params, char **ppdata, int total_data,
4926                                         unsigned int max_data_bytes)
4927 {
4928         char *params = *pparams;
4929
4930         DEBUG(3,("call_trans2findnotifynext\n"));
4931
4932         /* Realloc the parameter and data sizes */
4933         *pparams = (char *)SMB_REALLOC(*pparams,4);
4934         if (*pparams == NULL) {
4935                 return ERROR_NT(NT_STATUS_NO_MEMORY);
4936         }
4937         params = *pparams;
4938
4939         SSVAL(params,0,0); /* No changes */
4940         SSVAL(params,2,0); /* No EA errors */
4941
4942         send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0, max_data_bytes);
4943   
4944         return(-1);
4945 }
4946
4947 /****************************************************************************
4948  Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
4949 ****************************************************************************/
4950
4951 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4952                                         char **pparams, int total_params, char **ppdata, int total_data,
4953                                         unsigned int max_data_bytes)
4954 {
4955         char *params = *pparams;
4956         pstring pathname;
4957         int reply_size = 0;
4958         int max_referral_level;
4959
4960         DEBUG(10,("call_trans2getdfsreferral\n"));
4961
4962         if (total_params < 2) {
4963                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4964         }
4965
4966         max_referral_level = SVAL(params,0);
4967
4968         if(!lp_host_msdfs())
4969                 return ERROR_DOS(ERRDOS,ERRbadfunc);
4970
4971         srvstr_pull(inbuf, pathname, &params[2], sizeof(pathname), -1, STR_TERMINATE);
4972         if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
4973                 return UNIXERROR(ERRDOS,ERRbadfile);
4974     
4975         SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
4976         send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size, max_data_bytes);
4977
4978         return(-1);
4979 }
4980
4981 #define LMCAT_SPL       0x53
4982 #define LMFUNC_GETJOBID 0x60
4983
4984 /****************************************************************************
4985  Reply to a TRANS2_IOCTL - used for OS/2 printing.
4986 ****************************************************************************/
4987
4988 static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4989                                         char **pparams, int total_params, char **ppdata, int total_data,
4990                                         unsigned int max_data_bytes)
4991 {
4992         char *pdata = *ppdata;
4993         files_struct *fsp = file_fsp(inbuf,smb_vwv15);
4994
4995         /* check for an invalid fid before proceeding */
4996         
4997         if (!fsp)                                
4998                 return(ERROR_DOS(ERRDOS,ERRbadfid));  
4999
5000         if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
5001                         (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
5002                 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
5003                 if (*ppdata == NULL) {
5004                         return ERROR_NT(NT_STATUS_NO_MEMORY);
5005                 }
5006                 pdata = *ppdata;
5007
5008                 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
5009                         CAN ACCEPT THIS IN UNICODE. JRA. */
5010
5011                 SSVAL(pdata,0,fsp->rap_print_jobid);                     /* Job number */
5012                 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
5013                 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
5014                 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32, max_data_bytes);
5015                 return(-1);
5016         } else {
5017                 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
5018                 return ERROR_DOS(ERRSRV,ERRerror);
5019         }
5020 }
5021
5022 /****************************************************************************
5023  Reply to a SMBfindclose (stop trans2 directory search).
5024 ****************************************************************************/
5025
5026 int reply_findclose(connection_struct *conn,
5027                     char *inbuf,char *outbuf,int length,int bufsize)
5028 {
5029         int outsize = 0;
5030         int dptr_num=SVALS(inbuf,smb_vwv0);
5031         START_PROFILE(SMBfindclose);
5032
5033         DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
5034
5035         dptr_close(&dptr_num);
5036
5037         outsize = set_message(outbuf,0,0,False);
5038
5039         DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
5040
5041         END_PROFILE(SMBfindclose);
5042         return(outsize);
5043 }
5044
5045 /****************************************************************************
5046  Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
5047 ****************************************************************************/
5048
5049 int reply_findnclose(connection_struct *conn, 
5050                      char *inbuf,char *outbuf,int length,int bufsize)
5051 {
5052         int outsize = 0;
5053         int dptr_num= -1;
5054         START_PROFILE(SMBfindnclose);
5055         
5056         dptr_num = SVAL(inbuf,smb_vwv0);
5057
5058         DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
5059
5060         /* We never give out valid handles for a 
5061            findnotifyfirst - so any dptr_num is ok here. 
5062            Just ignore it. */
5063
5064         outsize = set_message(outbuf,0,0,False);
5065
5066         DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
5067
5068         END_PROFILE(SMBfindnclose);
5069         return(outsize);
5070 }
5071
5072 int handle_trans2(connection_struct *conn,
5073                   struct trans_state *state,
5074                   char *inbuf, char *outbuf, int size, int bufsize)
5075 {
5076         int outsize;
5077
5078         if (Protocol >= PROTOCOL_NT1) {
5079                 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
5080         }
5081
5082         /* Now we must call the relevant TRANS2 function */
5083         switch(state->call)  {
5084         case TRANSACT2_OPEN:
5085         {
5086                 START_PROFILE_NESTED(Trans2_open);
5087                 outsize = call_trans2open(
5088                         conn, inbuf, outbuf, bufsize, 
5089                         &state->param, state->total_param,
5090                         &state->data, state->total_data,
5091                         state->max_data_return);
5092                 END_PROFILE_NESTED(Trans2_open);
5093                 break;
5094         }
5095
5096         case TRANSACT2_FINDFIRST:
5097         {
5098                 START_PROFILE_NESTED(Trans2_findfirst);
5099                 outsize = call_trans2findfirst(
5100                         conn, inbuf, outbuf, bufsize,
5101                         &state->param, state->total_param,
5102                         &state->data, state->total_data,
5103                         state->max_data_return);
5104                 END_PROFILE_NESTED(Trans2_findfirst);
5105                 break;
5106         }
5107
5108         case TRANSACT2_FINDNEXT:
5109         {
5110                 START_PROFILE_NESTED(Trans2_findnext);
5111                 outsize = call_trans2findnext(
5112                         conn, inbuf, outbuf, size, bufsize, 
5113                         &state->param, state->total_param,
5114                         &state->data, state->total_data,
5115                         state->max_data_return);
5116                 END_PROFILE_NESTED(Trans2_findnext);
5117                 break;
5118         }
5119
5120         case TRANSACT2_QFSINFO:
5121         {
5122                 START_PROFILE_NESTED(Trans2_qfsinfo);
5123                 outsize = call_trans2qfsinfo(
5124                         conn, inbuf, outbuf, size, bufsize,
5125                         &state->param, state->total_param,
5126                         &state->data, state->total_data,
5127                         state->max_data_return);
5128                 END_PROFILE_NESTED(Trans2_qfsinfo);
5129             break;
5130         }
5131
5132         case TRANSACT2_SETFSINFO:
5133         {
5134                 START_PROFILE_NESTED(Trans2_setfsinfo);
5135                 outsize = call_trans2setfsinfo(
5136                         conn, inbuf, outbuf, size, bufsize, 
5137                         &state->param, state->total_param,
5138                         &state->data, state->total_data,
5139                         state->max_data_return);
5140                 END_PROFILE_NESTED(Trans2_setfsinfo);
5141                 break;
5142         }
5143
5144         case TRANSACT2_QPATHINFO:
5145         case TRANSACT2_QFILEINFO:
5146         {
5147                 START_PROFILE_NESTED(Trans2_qpathinfo);
5148                 outsize = call_trans2qfilepathinfo(
5149                         conn, inbuf, outbuf, size, bufsize, state->call,
5150                         &state->param, state->total_param,
5151                         &state->data, state->total_data,
5152                         state->max_data_return);
5153                 END_PROFILE_NESTED(Trans2_qpathinfo);
5154                 break;
5155         }
5156
5157         case TRANSACT2_SETPATHINFO:
5158         case TRANSACT2_SETFILEINFO:
5159         {
5160                 START_PROFILE_NESTED(Trans2_setpathinfo);
5161                 outsize = call_trans2setfilepathinfo(
5162                         conn, inbuf, outbuf, size, bufsize, state->call,
5163                         &state->param, state->total_param,
5164                         &state->data, state->total_data,
5165                         state->max_data_return);
5166                 END_PROFILE_NESTED(Trans2_setpathinfo);
5167                 break;
5168         }
5169
5170         case TRANSACT2_FINDNOTIFYFIRST:
5171         {
5172                 START_PROFILE_NESTED(Trans2_findnotifyfirst);
5173                 outsize = call_trans2findnotifyfirst(
5174                         conn, inbuf, outbuf, size, bufsize, 
5175                         &state->param, state->total_param,
5176                         &state->data, state->total_data,
5177                         state->max_data_return);
5178                 END_PROFILE_NESTED(Trans2_findnotifyfirst);
5179                 break;
5180         }
5181
5182         case TRANSACT2_FINDNOTIFYNEXT:
5183         {
5184                 START_PROFILE_NESTED(Trans2_findnotifynext);
5185                 outsize = call_trans2findnotifynext(
5186                         conn, inbuf, outbuf, size, bufsize, 
5187                         &state->param, state->total_param,
5188                         &state->data, state->total_data,
5189                         state->max_data_return);
5190                 END_PROFILE_NESTED(Trans2_findnotifynext);
5191                 break;
5192         }
5193
5194         case TRANSACT2_MKDIR:
5195         {
5196                 START_PROFILE_NESTED(Trans2_mkdir);
5197                 outsize = call_trans2mkdir(
5198                         conn, inbuf, outbuf, size, bufsize,
5199                         &state->param, state->total_param,
5200                         &state->data, state->total_data,
5201                         state->max_data_return);
5202                 END_PROFILE_NESTED(Trans2_mkdir);
5203                 break;
5204         }
5205
5206         case TRANSACT2_GET_DFS_REFERRAL:
5207         {
5208                 START_PROFILE_NESTED(Trans2_get_dfs_referral);
5209                 outsize = call_trans2getdfsreferral(
5210                         conn, inbuf, outbuf, size, bufsize,
5211                         &state->param, state->total_param,
5212                         &state->data, state->total_data,
5213                         state->max_data_return);
5214                 END_PROFILE_NESTED(Trans2_get_dfs_referral);
5215                 break;
5216         }
5217
5218         case TRANSACT2_IOCTL:
5219         {
5220                 START_PROFILE_NESTED(Trans2_ioctl);
5221                 outsize = call_trans2ioctl(
5222                         conn, inbuf, outbuf, size, bufsize,
5223                         &state->param, state->total_param,
5224                         &state->data, state->total_data,
5225                         state->max_data_return);
5226                 END_PROFILE_NESTED(Trans2_ioctl);
5227                 break;
5228         }
5229
5230         default:
5231                 /* Error in request */
5232                 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
5233                 outsize = ERROR_DOS(ERRSRV,ERRerror);
5234         }
5235
5236         return outsize;
5237 }
5238
5239 /****************************************************************************
5240  Reply to a SMBtrans2.
5241  ****************************************************************************/
5242
5243 int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf,
5244                  int size, int bufsize)
5245 {
5246         int outsize = 0;
5247         unsigned int dsoff = SVAL(inbuf, smb_dsoff);
5248         unsigned int dscnt = SVAL(inbuf, smb_dscnt);
5249         unsigned int psoff = SVAL(inbuf, smb_psoff);
5250         unsigned int pscnt = SVAL(inbuf, smb_pscnt);
5251         unsigned int tran_call = SVAL(inbuf, smb_setup0);
5252         struct trans_state *state;
5253         NTSTATUS result;
5254
5255         START_PROFILE(SMBtrans2);
5256
5257         result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid));
5258         if (!NT_STATUS_IS_OK(result)) {
5259                 DEBUG(2, ("Got invalid trans2 request: %s\n",
5260                           nt_errstr(result)));
5261                 END_PROFILE(SMBtrans2);
5262                 return ERROR_NT(result);
5263         }
5264
5265         if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
5266             && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
5267                 END_PROFILE(SMBtrans2);
5268                 return ERROR_DOS(ERRSRV,ERRaccess);
5269         }
5270
5271         if ((state = TALLOC_P(conn->mem_ctx, struct trans_state)) == NULL) {
5272                 DEBUG(0, ("talloc failed\n"));
5273                 END_PROFILE(SMBtrans2);
5274                 return ERROR_NT(NT_STATUS_NO_MEMORY);
5275         }
5276
5277         state->cmd = SMBtrans2;
5278
5279         state->mid = SVAL(inbuf, smb_mid);
5280         state->vuid = SVAL(inbuf, smb_uid);
5281         state->setup_count = SVAL(inbuf, smb_suwcnt);
5282         state->setup = NULL;
5283         state->total_param = SVAL(inbuf, smb_tpscnt);
5284         state->param = NULL;
5285         state->total_data =  SVAL(inbuf, smb_tdscnt);
5286         state->data = NULL;
5287         state->max_param_return = SVAL(inbuf, smb_mprcnt);
5288         state->max_data_return  = SVAL(inbuf, smb_mdrcnt);
5289         state->max_setup_return = SVAL(inbuf, smb_msrcnt);
5290         state->close_on_completion = BITSETW(inbuf+smb_vwv5,0);
5291         state->one_way = BITSETW(inbuf+smb_vwv5,1);
5292
5293         state->call = tran_call;
5294
5295         /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
5296            is so as a sanity check */
5297         if (state->setup_count != 1) {
5298                 /*
5299                  * Need to have rc=0 for ioctl to get job id for OS/2.
5300                  *  Network printing will fail if function is not successful.
5301                  *  Similar function in reply.c will be used if protocol
5302                  *  is LANMAN1.0 instead of LM1.2X002.
5303                  *  Until DosPrintSetJobInfo with PRJINFO3 is supported,
5304                  *  outbuf doesn't have to be set(only job id is used).
5305                  */
5306                 if ( (state->setup_count == 4) && (tran_call == TRANSACT2_IOCTL) &&
5307                                 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
5308                                 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
5309                         DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
5310                 } else {
5311                         DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
5312                         DEBUG(2,("Transaction is %d\n",tran_call));
5313                         TALLOC_FREE(state);
5314                         END_PROFILE(SMBtrans2);
5315                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5316                 }
5317         }
5318
5319         if ((dscnt > state->total_data) || (pscnt > state->total_param))
5320                 goto bad_param;
5321
5322         if (state->total_data) {
5323                 /* Can't use talloc here, the core routines do realloc on the
5324                  * params and data. */
5325                 state->data = (char *)SMB_MALLOC(state->total_data);
5326                 if (state->data == NULL) {
5327                         DEBUG(0,("reply_trans2: data malloc fail for %u "
5328                                  "bytes !\n", (unsigned int)state->total_data));
5329                         TALLOC_FREE(state);
5330                         END_PROFILE(SMBtrans2);
5331                         return(ERROR_DOS(ERRDOS,ERRnomem));
5332                 }
5333                 if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
5334                         goto bad_param;
5335                 if ((smb_base(inbuf)+dsoff+dscnt > inbuf + size) ||
5336                     (smb_base(inbuf)+dsoff+dscnt < smb_base(inbuf)))
5337                         goto bad_param;
5338
5339                 memcpy(state->data,smb_base(inbuf)+dsoff,dscnt);
5340         }
5341
5342         if (state->total_param) {
5343                 /* Can't use talloc here, the core routines do realloc on the
5344                  * params and data. */
5345                 state->param = (char *)SMB_MALLOC(state->total_param);
5346                 if (state->param == NULL) {
5347                         DEBUG(0,("reply_trans: param malloc fail for %u "
5348                                  "bytes !\n", (unsigned int)state->total_param));
5349                         SAFE_FREE(state->data);
5350                         TALLOC_FREE(state);
5351                         END_PROFILE(SMBtrans2);
5352                         return(ERROR_DOS(ERRDOS,ERRnomem));
5353                 } 
5354                 if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt))
5355                         goto bad_param;
5356                 if ((smb_base(inbuf)+psoff+pscnt > inbuf + size) ||
5357                     (smb_base(inbuf)+psoff+pscnt < smb_base(inbuf)))
5358                         goto bad_param;
5359
5360                 memcpy(state->param,smb_base(inbuf)+psoff,pscnt);
5361         }
5362
5363         state->received_data  = dscnt;
5364         state->received_param = pscnt;
5365
5366         if ((state->received_param == state->total_param) &&
5367             (state->received_data == state->total_data)) {
5368
5369                 outsize = handle_trans2(conn, state, inbuf, outbuf,
5370                                         size, bufsize);
5371                 SAFE_FREE(state->data);
5372                 SAFE_FREE(state->param);
5373                 TALLOC_FREE(state);
5374                 END_PROFILE(SMBtrans2);
5375                 return outsize;
5376         }
5377
5378         DLIST_ADD(conn->pending_trans, state);
5379
5380         /* We need to send an interim response then receive the rest
5381            of the parameter/data bytes */
5382         outsize = set_message(outbuf,0,0,False);
5383         show_msg(outbuf);
5384         END_PROFILE(SMBtrans2);
5385         return outsize;
5386
5387   bad_param:
5388
5389         DEBUG(0,("reply_trans2: invalid trans parameters\n"));
5390         SAFE_FREE(state->data);
5391         SAFE_FREE(state->param);
5392         TALLOC_FREE(state);
5393         END_PROFILE(SMBtrans2);
5394         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5395 }
5396
5397
5398 /****************************************************************************
5399  Reply to a SMBtranss2
5400  ****************************************************************************/
5401
5402 int reply_transs2(connection_struct *conn,
5403                   char *inbuf,char *outbuf,int size,int bufsize)
5404 {
5405         int outsize = 0;
5406         unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
5407         struct trans_state *state;
5408
5409         START_PROFILE(SMBtranss2);
5410
5411         show_msg(inbuf);
5412
5413         for (state = conn->pending_trans; state != NULL;
5414              state = state->next) {
5415                 if (state->mid == SVAL(inbuf,smb_mid)) {
5416                         break;
5417                 }
5418         }
5419
5420         if ((state == NULL) || (state->cmd != SMBtrans2)) {
5421                 END_PROFILE(SMBtranss2);
5422                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5423         }
5424
5425         /* Revise state->total_param and state->total_data in case they have
5426            changed downwards */
5427
5428         if (SVAL(inbuf, smb_tpscnt) < state->total_param)
5429                 state->total_param = SVAL(inbuf, smb_tpscnt);
5430         if (SVAL(inbuf, smb_tdscnt) < state->total_data)
5431                 state->total_data = SVAL(inbuf, smb_tdscnt);
5432
5433         pcnt = SVAL(inbuf, smb_spscnt);
5434         poff = SVAL(inbuf, smb_spsoff);
5435         pdisp = SVAL(inbuf, smb_spsdisp);
5436
5437         dcnt = SVAL(inbuf, smb_sdscnt);
5438         doff = SVAL(inbuf, smb_sdsoff);
5439         ddisp = SVAL(inbuf, smb_sdsdisp);
5440
5441         state->received_param += pcnt;
5442         state->received_data += dcnt;
5443                 
5444         if ((state->received_data > state->total_data) ||
5445             (state->received_param > state->total_param))
5446                 goto bad_param;
5447
5448         if (pcnt) {
5449                 if (pdisp+pcnt > state->total_param)
5450                         goto bad_param;
5451                 if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt))
5452                         goto bad_param;
5453                 if (pdisp > state->total_param)
5454                         goto bad_param;
5455                 if ((smb_base(inbuf) + poff + pcnt > inbuf + size) ||
5456                     (smb_base(inbuf) + poff + pcnt < smb_base(inbuf)))
5457                         goto bad_param;
5458                 if (state->param + pdisp < state->param)
5459                         goto bad_param;
5460
5461                 memcpy(state->param+pdisp,smb_base(inbuf)+poff,
5462                        pcnt);
5463         }
5464
5465         if (dcnt) {
5466                 if (ddisp+dcnt > state->total_data)
5467                         goto bad_param;
5468                 if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt))
5469                         goto bad_param;
5470                 if (ddisp > state->total_data)
5471                         goto bad_param;
5472                 if ((smb_base(inbuf) + doff + dcnt > inbuf + size) ||
5473                     (smb_base(inbuf) + doff + dcnt < smb_base(inbuf)))
5474                         goto bad_param;
5475                 if (state->data + ddisp < state->data)
5476                         goto bad_param;
5477
5478                 memcpy(state->data+ddisp, smb_base(inbuf)+doff,
5479                        dcnt);      
5480         }
5481
5482         if ((state->received_param < state->total_param) ||
5483             (state->received_data < state->total_data)) {
5484                 END_PROFILE(SMBtranss2);
5485                 return -1;
5486         }
5487
5488         /* construct_reply_common has done us the favor to pre-fill the
5489          * command field with SMBtranss2 which is wrong :-)
5490          */
5491         SCVAL(outbuf,smb_com,SMBtrans2);
5492
5493         outsize = handle_trans2(conn, state, inbuf, outbuf, size, bufsize);
5494
5495         DLIST_REMOVE(conn->pending_trans, state);
5496         SAFE_FREE(state->data);
5497         SAFE_FREE(state->param);
5498         TALLOC_FREE(state);
5499
5500         if (outsize == 0) {
5501                 END_PROFILE(SMBtranss2);
5502                 return(ERROR_DOS(ERRSRV,ERRnosupport));
5503         }
5504         
5505         END_PROFILE(SMBtranss2);
5506         return(outsize);
5507
5508   bad_param:
5509
5510         DEBUG(0,("reply_transs2: invalid trans parameters\n"));
5511         DLIST_REMOVE(conn->pending_trans, state);
5512         SAFE_FREE(state->data);
5513         SAFE_FREE(state->param);
5514         TALLOC_FREE(state);
5515         END_PROFILE(SMBtranss2);
5516         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5517 }