r21645: Make posix_unlink work - on open files too !
[samba.git] / source / smbd / trans2.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB transaction2 handling
4    Copyright (C) Jeremy Allison                 1994-2007
5    Copyright (C) Stefan (metze) Metzmacher      2003
6    Copyright (C) Volker Lendecke                2005
7    Copyright (C) Steve French                   2005
8
9    Extensively modified by Andrew Tridgell, 1995
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 2 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 #include "includes.h"
27
28 extern int max_send;
29 extern enum protocol_types Protocol;
30 extern int smb_read_error;
31 extern uint32 global_client_caps;
32 extern struct current_user current_user;
33
34 #define get_file_size(sbuf) ((sbuf).st_size)
35 #define DIR_ENTRY_SAFETY_MARGIN 4096
36
37 /********************************************************************
38  Roundup a value to the nearest allocation roundup size boundary.
39  Only do this for Windows clients.
40 ********************************************************************/
41
42 SMB_BIG_UINT smb_roundup(connection_struct *conn, SMB_BIG_UINT val)
43 {
44         SMB_BIG_UINT rval = lp_allocation_roundup_size(SNUM(conn));
45
46         /* Only roundup for Windows clients. */
47         enum remote_arch_types ra_type = get_remote_arch();
48         if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
49                 val = SMB_ROUNDUP(val,rval);
50         }
51         return val;
52 }
53
54 /********************************************************************
55  Given a stat buffer return the allocated size on disk, taking into
56  account sparse files.
57 ********************************************************************/
58
59 SMB_BIG_UINT get_allocation_size(connection_struct *conn, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
60 {
61         SMB_BIG_UINT ret;
62
63         if(S_ISDIR(sbuf->st_mode)) {
64                 return 0;
65         }
66
67 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
68         ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
69 #else
70         ret = (SMB_BIG_UINT)get_file_size(*sbuf);
71 #endif
72
73         if (fsp && fsp->initial_allocation_size)
74                 ret = MAX(ret,fsp->initial_allocation_size);
75
76         return smb_roundup(conn, ret);
77 }
78
79 /****************************************************************************
80  Utility functions for dealing with extended attributes.
81 ****************************************************************************/
82
83 static const char *prohibited_ea_names[] = {
84         SAMBA_POSIX_INHERITANCE_EA_NAME,
85         SAMBA_XATTR_DOS_ATTRIB,
86         NULL
87 };
88
89 /****************************************************************************
90  Refuse to allow clients to overwrite our private xattrs.
91 ****************************************************************************/
92
93 static BOOL samba_private_attr_name(const char *unix_ea_name)
94 {
95         int i;
96
97         for (i = 0; prohibited_ea_names[i]; i++) {
98                 if (strequal( prohibited_ea_names[i], unix_ea_name))
99                         return True;
100         }
101         return False;
102 }
103
104 /****************************************************************************
105  Get one EA value. Fill in a struct ea_struct.
106 ****************************************************************************/
107
108 static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
109                                 const char *fname, char *ea_name, struct ea_struct *pea)
110 {
111         /* Get the value of this xattr. Max size is 64k. */
112         size_t attr_size = 256;
113         char *val = NULL;
114         ssize_t sizeret;
115
116  again:
117
118         val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size);
119         if (!val) {
120                 return False;
121         }
122
123         if (fsp && fsp->fh->fd != -1) {
124                 sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fh->fd, ea_name, val, attr_size);
125         } else {
126                 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
127         }
128
129         if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
130                 attr_size = 65536;
131                 goto again;
132         }
133
134         if (sizeret == -1) {
135                 return False;
136         }
137
138         DEBUG(10,("get_ea_value: EA %s is of length %u: ", ea_name, (unsigned int)sizeret));
139         dump_data(10, val, sizeret);
140
141         pea->flags = 0;
142         if (strnequal(ea_name, "user.", 5)) {
143                 pea->name = &ea_name[5];
144         } else {
145                 pea->name = ea_name;
146         }
147         pea->value.data = (unsigned char *)val;
148         pea->value.length = (size_t)sizeret;
149         return True;
150 }
151
152 /****************************************************************************
153  Return a linked list of the total EA's. Plus the total size
154 ****************************************************************************/
155
156 static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
157                                         const char *fname, size_t *pea_total_len)
158 {
159         /* Get a list of all xattrs. Max namesize is 64k. */
160         size_t ea_namelist_size = 1024;
161         char *ea_namelist;
162         char *p;
163         ssize_t sizeret;
164         int i;
165         struct ea_list *ea_list_head = NULL;
166
167         *pea_total_len = 0;
168
169         if (!lp_ea_support(SNUM(conn))) {
170                 return NULL;
171         }
172
173         for (i = 0, ea_namelist = TALLOC_ARRAY(mem_ctx, char, ea_namelist_size); i < 6;
174              ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) {
175
176                 if (!ea_namelist) {
177                         return NULL;
178                 }
179
180                 if (fsp && fsp->fh->fd != -1) {
181                         sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fh->fd, ea_namelist, ea_namelist_size);
182                 } else {
183                         sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size);
184                 }
185
186                 if (sizeret == -1 && errno == ERANGE) {
187                         ea_namelist_size *= 2;
188                 } else {
189                         break;
190                 }
191         }
192
193         if (sizeret == -1)
194                 return NULL;
195
196         DEBUG(10,("get_ea_list_from_file: ea_namelist size = %u\n", (unsigned int)sizeret ));
197
198         if (sizeret) {
199                 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) {
200                         struct ea_list *listp;
201
202                         if (strnequal(p, "system.", 7) || samba_private_attr_name(p))
203                                 continue;
204                 
205                         listp = TALLOC_P(mem_ctx, struct ea_list);
206                         if (!listp)
207                                 return NULL;
208
209                         if (!get_ea_value(mem_ctx, conn, fsp, fname, p, &listp->ea)) {
210                                 return NULL;
211                         }
212
213                         {
214                                 fstring dos_ea_name;
215                                 push_ascii_fstring(dos_ea_name, listp->ea.name);
216                                 *pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
217                                 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len = %u\n",
218                                         (unsigned int)*pea_total_len, dos_ea_name,
219                                         (unsigned int)listp->ea.value.length ));
220                         }
221                         DLIST_ADD_END(ea_list_head, listp, struct ea_list *);
222                 }
223                 /* Add on 4 for total length. */
224                 if (*pea_total_len) {
225                         *pea_total_len += 4;
226                 }
227         }
228
229         DEBUG(10,("get_ea_list_from_file: total_len = %u\n", (unsigned int)*pea_total_len));
230         return ea_list_head;
231 }
232
233 /****************************************************************************
234  Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
235  that was filled.
236 ****************************************************************************/
237
238 static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
239         connection_struct *conn, struct ea_list *ea_list)
240 {
241         unsigned int ret_data_size = 4;
242         char *p = pdata;
243
244         SMB_ASSERT(total_data_size >= 4);
245
246         if (!lp_ea_support(SNUM(conn))) {
247                 SIVAL(pdata,4,0);
248                 return 4;
249         }
250
251         for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
252                 size_t dos_namelen;
253                 fstring dos_ea_name;
254                 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
255                 dos_namelen = strlen(dos_ea_name);
256                 if (dos_namelen > 255 || dos_namelen == 0) {
257                         break;
258                 }
259                 if (ea_list->ea.value.length > 65535) {
260                         break;
261                 }
262                 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
263                         break;
264                 }
265
266                 /* We know we have room. */
267                 SCVAL(p,0,ea_list->ea.flags);
268                 SCVAL(p,1,dos_namelen);
269                 SSVAL(p,2,ea_list->ea.value.length);
270                 fstrcpy(p+4, dos_ea_name);
271                 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
272
273                 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
274                 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
275         }
276
277         ret_data_size = PTR_DIFF(p, pdata);
278         DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
279         SIVAL(pdata,0,ret_data_size);
280         return ret_data_size;
281 }
282
283 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
284 {
285         size_t total_ea_len = 0;
286         TALLOC_CTX *mem_ctx = NULL;
287
288         if (!lp_ea_support(SNUM(conn))) {
289                 return 0;
290         }
291         mem_ctx = talloc_init("estimate_ea_size");
292         (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
293         talloc_destroy(mem_ctx);
294         return total_ea_len;
295 }
296
297 /****************************************************************************
298  Ensure the EA name is case insensitive by matching any existing EA name.
299 ****************************************************************************/
300
301 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
302 {
303         size_t total_ea_len;
304         TALLOC_CTX *mem_ctx = talloc_init("canonicalize_ea_name");
305         struct ea_list *ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
306
307         for (; ea_list; ea_list = ea_list->next) {
308                 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
309                         DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
310                                 &unix_ea_name[5], ea_list->ea.name));
311                         safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
312                         break;
313                 }
314         }
315         talloc_destroy(mem_ctx);
316 }
317
318 /****************************************************************************
319  Set or delete an extended attribute.
320 ****************************************************************************/
321
322 NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, struct ea_list *ea_list)
323 {
324         if (!lp_ea_support(SNUM(conn))) {
325                 return NT_STATUS_EAS_NOT_SUPPORTED;
326         }
327
328         for (;ea_list; ea_list = ea_list->next) {
329                 int ret;
330                 fstring unix_ea_name;
331
332                 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
333                 fstrcat(unix_ea_name, ea_list->ea.name);
334
335                 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
336
337                 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
338
339                 if (samba_private_attr_name(unix_ea_name)) {
340                         DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
341                         return NT_STATUS_ACCESS_DENIED;
342                 }
343
344                 if (ea_list->ea.value.length == 0) {
345                         /* Remove the attribute. */
346                         if (fsp && (fsp->fh->fd != -1)) {
347                                 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
348                                         unix_ea_name, fsp->fsp_name));
349                                 ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fh->fd, unix_ea_name);
350                         } else {
351                                 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
352                                         unix_ea_name, fname));
353                                 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
354                         }
355 #ifdef ENOATTR
356                         /* Removing a non existent attribute always succeeds. */
357                         if (ret == -1 && errno == ENOATTR) {
358                                 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
359                                                 unix_ea_name));
360                                 ret = 0;
361                         }
362 #endif
363                 } else {
364                         if (fsp && (fsp->fh->fd != -1)) {
365                                 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
366                                         unix_ea_name, fsp->fsp_name));
367                                 ret = SMB_VFS_FSETXATTR(fsp, fsp->fh->fd, unix_ea_name,
368                                                         ea_list->ea.value.data, ea_list->ea.value.length, 0);
369                         } else {
370                                 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
371                                         unix_ea_name, fname));
372                                 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
373                                                         ea_list->ea.value.data, ea_list->ea.value.length, 0);
374                         }
375                 }
376
377                 if (ret == -1) {
378 #ifdef ENOTSUP
379                         if (errno == ENOTSUP) {
380                                 return NT_STATUS_EAS_NOT_SUPPORTED;
381                         }
382 #endif
383                         return map_nt_error_from_unix(errno);
384                 }
385
386         }
387         return NT_STATUS_OK;
388 }
389 /****************************************************************************
390  Read a list of EA names from an incoming data buffer. Create an ea_list with them.
391 ****************************************************************************/
392
393 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
394 {
395         struct ea_list *ea_list_head = NULL;
396         size_t offset = 0;
397
398         while (offset + 2 < data_size) {
399                 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
400                 unsigned int namelen = CVAL(pdata,offset);
401
402                 offset++; /* Go past the namelen byte. */
403
404                 /* integer wrap paranioa. */
405                 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
406                                 (offset > data_size) || (namelen > data_size) ||
407                                 (offset + namelen >= data_size)) {
408                         break;
409                 }
410                 /* Ensure the name is null terminated. */
411                 if (pdata[offset + namelen] != '\0') {
412                         return NULL;
413                 }
414                 pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset]);
415                 if (!eal->ea.name) {
416                         return NULL;
417                 }
418
419                 offset += (namelen + 1); /* Go past the name + terminating zero. */
420                 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
421                 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
422         }
423
424         return ea_list_head;
425 }
426
427 /****************************************************************************
428  Read one EA list entry from the buffer.
429 ****************************************************************************/
430
431 struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
432 {
433         struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
434         uint16 val_len;
435         unsigned int namelen;
436
437         if (!eal) {
438                 return NULL;
439         }
440
441         if (data_size < 6) {
442                 return NULL;
443         }
444
445         eal->ea.flags = CVAL(pdata,0);
446         namelen = CVAL(pdata,1);
447         val_len = SVAL(pdata,2);
448
449         if (4 + namelen + 1 + val_len > data_size) {
450                 return NULL;
451         }
452
453         /* Ensure the name is null terminated. */
454         if (pdata[namelen + 4] != '\0') {
455                 return NULL;
456         }
457         pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4);
458         if (!eal->ea.name) {
459                 return NULL;
460         }
461
462         eal->ea.value = data_blob_talloc(eal, NULL, (size_t)val_len + 1);
463         if (!eal->ea.value.data) {
464                 return NULL;
465         }
466
467         memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
468
469         /* Ensure we're null terminated just in case we print the value. */
470         eal->ea.value.data[val_len] = '\0';
471         /* But don't count the null. */
472         eal->ea.value.length--;
473
474         if (pbytes_used) {
475                 *pbytes_used = 4 + namelen + 1 + val_len;
476         }
477
478         DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
479         dump_data(10, (const char *)eal->ea.value.data, eal->ea.value.length);
480
481         return eal;
482 }
483
484 /****************************************************************************
485  Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
486 ****************************************************************************/
487
488 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
489 {
490         struct ea_list *ea_list_head = NULL;
491         size_t offset = 0;
492         size_t bytes_used = 0;
493
494         while (offset < data_size) {
495                 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
496
497                 if (!eal) {
498                         return NULL;
499                 }
500
501                 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
502                 offset += bytes_used;
503         }
504
505         return ea_list_head;
506 }
507
508 /****************************************************************************
509  Count the total EA size needed.
510 ****************************************************************************/
511
512 static size_t ea_list_size(struct ea_list *ealist)
513 {
514         fstring dos_ea_name;
515         struct ea_list *listp;
516         size_t ret = 0;
517
518         for (listp = ealist; listp; listp = listp->next) {
519                 push_ascii_fstring(dos_ea_name, listp->ea.name);
520                 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
521         }
522         /* Add on 4 for total length. */
523         if (ret) {
524                 ret += 4;
525         }
526
527         return ret;
528 }
529
530 /****************************************************************************
531  Return a union of EA's from a file list and a list of names.
532  The TALLOC context for the two lists *MUST* be identical as we steal
533  memory from one list to add to another. JRA.
534 ****************************************************************************/
535
536 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
537 {
538         struct ea_list *nlistp, *flistp;
539
540         for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
541                 for (flistp = file_list; flistp; flistp = flistp->next) {
542                         if (strequal(nlistp->ea.name, flistp->ea.name)) {
543                                 break;
544                         }
545                 }
546
547                 if (flistp) {
548                         /* Copy the data from this entry. */
549                         nlistp->ea.flags = flistp->ea.flags;
550                         nlistp->ea.value = flistp->ea.value;
551                 } else {
552                         /* Null entry. */
553                         nlistp->ea.flags = 0;
554                         ZERO_STRUCT(nlistp->ea.value);
555                 }
556         }
557
558         *total_ea_len = ea_list_size(name_list);
559         return name_list;
560 }
561
562 /****************************************************************************
563   Send the required number of replies back.
564   We assume all fields other than the data fields are
565   set correctly for the type of call.
566   HACK ! Always assumes smb_setup field is zero.
567 ****************************************************************************/
568
569 int send_trans2_replies(char *outbuf,
570                         int bufsize,
571                         const char *params, 
572                         int paramsize,
573                         const 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         const char *pp = params;
587         const char *pd = pdata;
588         int params_sent_thistime, data_sent_thistime, total_sent_thistime;
589         int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
590         int data_alignment_offset = 0;
591
592         /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
593         
594         set_message(outbuf,10,0,True);
595
596         /* Modify the data_to_send and datasize and set the error if
597            we're trying to send more than max_data_bytes. We still send
598            the part of the packet(s) that fit. Strange, but needed
599            for OS/2. */
600
601         if (max_data_bytes > 0 && datasize > max_data_bytes) {
602                 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
603                         max_data_bytes, datasize ));
604                 datasize = data_to_send = max_data_bytes;
605                 error_packet_set(outbuf,ERRDOS,ERRbufferoverflow,STATUS_BUFFER_OVERFLOW,__LINE__,__FILE__);
606         }
607
608         /* If there genuinely are no parameters or data to send just send the empty packet */
609
610         if(params_to_send == 0 && data_to_send == 0) {
611                 show_msg(outbuf);
612                 if (!send_smb(smbd_server_fd(),outbuf))
613                         exit_server_cleanly("send_trans2_replies: send_smb failed.");
614                 return 0;
615         }
616
617         /* When sending params and data ensure that both are nicely aligned */
618         /* Only do this alignment when there is also data to send - else
619                 can cause NT redirector problems. */
620
621         if (((params_to_send % 4) != 0) && (data_to_send != 0))
622                 data_alignment_offset = 4 - (params_to_send % 4);
623
624         /* Space is bufsize minus Netbios over TCP header minus SMB header */
625         /* The alignment_offset is to align the param bytes on an even byte
626                 boundary. NT 4.0 Beta needs this to work correctly. */
627
628         useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
629
630         /* useable_space can never be more than max_send minus the alignment offset. */
631
632         useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
633
634         while (params_to_send || data_to_send) {
635                 /* Calculate whether we will totally or partially fill this packet */
636
637                 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
638
639                 /* We can never send more than useable_space */
640                 /*
641                  * Note that 'useable_space' does not include the alignment offsets,
642                  * but we must include the alignment offsets in the calculation of
643                  * the length of the data we send over the wire, as the alignment offsets
644                  * are sent here. Fix from Marc_Jacobsen@hp.com.
645                  */
646
647                 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
648
649                 set_message(outbuf, 10, total_sent_thistime, True);
650
651                 /* Set total params and data to be sent */
652                 SSVAL(outbuf,smb_tprcnt,paramsize);
653                 SSVAL(outbuf,smb_tdrcnt,datasize);
654
655                 /* Calculate how many parameters and data we can fit into
656                  * this packet. Parameters get precedence
657                  */
658
659                 params_sent_thistime = MIN(params_to_send,useable_space);
660                 data_sent_thistime = useable_space - params_sent_thistime;
661                 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
662
663                 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
664
665                 /* smb_proff is the offset from the start of the SMB header to the
666                         parameter bytes, however the first 4 bytes of outbuf are
667                         the Netbios over TCP header. Thus use smb_base() to subtract
668                         them from the calculation */
669
670                 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
671
672                 if(params_sent_thistime == 0)
673                         SSVAL(outbuf,smb_prdisp,0);
674                 else
675                         /* Absolute displacement of param bytes sent in this packet */
676                         SSVAL(outbuf,smb_prdisp,pp - params);
677
678                 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
679                 if(data_sent_thistime == 0) {
680                         SSVAL(outbuf,smb_droff,0);
681                         SSVAL(outbuf,smb_drdisp, 0);
682                 } else {
683                         /* The offset of the data bytes is the offset of the
684                                 parameter bytes plus the number of parameters being sent this time */
685                         SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) - 
686                                 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
687                         SSVAL(outbuf,smb_drdisp, pd - pdata);
688                 }
689
690                 /* Copy the param bytes into the packet */
691
692                 if(params_sent_thistime)
693                         memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
694
695                 /* Copy in the data bytes */
696                 if(data_sent_thistime)
697                         memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
698                                 data_alignment_offset,pd,data_sent_thistime);
699
700                 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
701                         params_sent_thistime, data_sent_thistime, useable_space));
702                 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
703                         params_to_send, data_to_send, paramsize, datasize));
704
705                 /* Send the packet */
706                 show_msg(outbuf);
707                 if (!send_smb(smbd_server_fd(),outbuf))
708                         exit_server_cleanly("send_trans2_replies: send_smb failed.");
709
710                 pp += params_sent_thistime;
711                 pd += data_sent_thistime;
712
713                 params_to_send -= params_sent_thistime;
714                 data_to_send -= data_sent_thistime;
715
716                 /* Sanity check */
717                 if(params_to_send < 0 || data_to_send < 0) {
718                         DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
719                                 params_to_send, data_to_send));
720                         return -1;
721                 }
722         }
723
724         return 0;
725 }
726
727 /****************************************************************************
728  Reply to a TRANSACT2_OPEN.
729 ****************************************************************************/
730
731 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,  
732                                 char **pparams, int total_params, char **ppdata, int total_data,
733                                 unsigned int max_data_bytes)
734 {
735         char *params = *pparams;
736         char *pdata = *ppdata;
737         int deny_mode;
738         int32 open_attr;
739         BOOL oplock_request;
740 #if 0
741         BOOL return_additional_info;
742         int16 open_sattr;
743         time_t open_time;
744 #endif
745         int open_ofun;
746         uint32 open_size;
747         char *pname;
748         pstring fname;
749         SMB_OFF_T size=0;
750         int fattr=0,mtime=0;
751         SMB_INO_T inode = 0;
752         SMB_STRUCT_STAT sbuf;
753         int smb_action = 0;
754         files_struct *fsp;
755         struct ea_list *ea_list = NULL;
756         uint16 flags = 0;
757         NTSTATUS status;
758         uint32 access_mask;
759         uint32 share_mode;
760         uint32 create_disposition;
761         uint32 create_options = 0;
762
763         /*
764          * Ensure we have enough parameters to perform the operation.
765          */
766
767         if (total_params < 29) {
768                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
769         }
770
771         flags = SVAL(params, 0);
772         deny_mode = SVAL(params, 2);
773         open_attr = SVAL(params,6);
774         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
775         if (oplock_request) {
776                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
777         }
778
779 #if 0
780         return_additional_info = BITSETW(params,0);
781         open_sattr = SVAL(params, 4);
782         open_time = make_unix_date3(params+8);
783 #endif
784         open_ofun = SVAL(params,12);
785         open_size = IVAL(params,14);
786         pname = &params[28];
787
788         if (IS_IPC(conn)) {
789                 return(ERROR_DOS(ERRSRV,ERRaccess));
790         }
791
792         srvstr_get_path(inbuf, fname, pname, sizeof(fname), total_params - 28, STR_TERMINATE, &status);
793         if (!NT_STATUS_IS_OK(status)) {
794                 return ERROR_NT(status);
795         }
796
797         DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
798                 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
799                 (unsigned int)open_ofun, open_size));
800
801         /* XXXX we need to handle passed times, sattr and flags */
802
803         status = unix_convert(conn, fname, False, NULL, &sbuf);
804         if (!NT_STATUS_IS_OK(status)) {
805                 return ERROR_NT(status);
806         }
807     
808         status = check_name(conn, fname);
809         if (!NT_STATUS_IS_OK(status)) {
810                 return ERROR_NT(status);
811         }
812
813         if (open_ofun == 0) {
814                 return ERROR_NT(NT_STATUS_OBJECT_NAME_COLLISION);
815         }
816
817         if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun,
818                                 &access_mask,
819                                 &share_mode,
820                                 &create_disposition,
821                                 &create_options)) {
822                 return ERROR_DOS(ERRDOS, ERRbadaccess);
823         }
824
825         /* Any data in this call is an EA list. */
826         if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
827                 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
828         }
829
830         if (total_data != 4) {
831                 if (total_data < 10) {
832                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
833                 }
834
835                 if (IVAL(pdata,0) > total_data) {
836                         DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
837                                 IVAL(pdata,0), (unsigned int)total_data));
838                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
839                 }
840
841                 ea_list = read_ea_list(tmp_talloc_ctx(), pdata + 4,
842                                        total_data - 4);
843                 if (!ea_list) {
844                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
845                 }
846         } else if (IVAL(pdata,0) != 4) {
847                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
848         }
849
850         status = open_file_ntcreate(conn,fname,&sbuf,
851                 access_mask,
852                 share_mode,
853                 create_disposition,
854                 create_options,
855                 open_attr,
856                 oplock_request,
857                 &smb_action, &fsp);
858       
859         if (!NT_STATUS_IS_OK(status)) {
860                 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
861                         /* We have re-scheduled this call. */
862                         return -1;
863                 }
864                 return ERROR_NT(status);
865         }
866
867         size = get_file_size(sbuf);
868         fattr = dos_mode(conn,fname,&sbuf);
869         mtime = sbuf.st_mtime;
870         inode = sbuf.st_ino;
871         if (fattr & aDIR) {
872                 close_file(fsp,ERROR_CLOSE);
873                 return(ERROR_DOS(ERRDOS,ERRnoaccess));
874         }
875
876         /* Save the requested allocation size. */
877         /* Allocate space for the file if a size hint is supplied */
878         if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) {
879                 SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)open_size;
880                 if (allocation_size && (allocation_size > (SMB_BIG_UINT)size)) {
881                         fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
882                         if (fsp->is_directory) {
883                                 close_file(fsp,ERROR_CLOSE);
884                                 /* Can't set allocation size on a directory. */
885                                 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
886                         }
887                         if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
888                                 close_file(fsp,ERROR_CLOSE);
889                                 return ERROR_NT(NT_STATUS_DISK_FULL);
890                         }
891
892                         /* Adjust size here to return the right size in the reply.
893                            Windows does it this way. */
894                         size = fsp->initial_allocation_size;
895                 } else {
896                         fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)size);
897                 }
898         }
899
900         if (ea_list && smb_action == FILE_WAS_CREATED) {
901                 status = set_ea(conn, fsp, fname, ea_list);
902                 if (!NT_STATUS_IS_OK(status)) {
903                         close_file(fsp,ERROR_CLOSE);
904                         return ERROR_NT(status);
905                 }
906         }
907
908         /* Realloc the size of parameters and data we will return */
909         *pparams = (char *)SMB_REALLOC(*pparams, 30);
910         if(*pparams == NULL ) {
911                 return ERROR_NT(NT_STATUS_NO_MEMORY);
912         }
913         params = *pparams;
914
915         SSVAL(params,0,fsp->fnum);
916         SSVAL(params,2,fattr);
917         srv_put_dos_date2(params,4, mtime);
918         SIVAL(params,8, (uint32)size);
919         SSVAL(params,12,deny_mode);
920         SSVAL(params,14,0); /* open_type - file or directory. */
921         SSVAL(params,16,0); /* open_state - only valid for IPC device. */
922
923         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
924                 smb_action |= EXTENDED_OPLOCK_GRANTED;
925         }
926
927         SSVAL(params,18,smb_action);
928
929         /*
930          * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
931          */
932         SIVAL(params,20,inode);
933         SSVAL(params,24,0); /* Padding. */
934         if (flags & 8) {
935                 uint32 ea_size = estimate_ea_size(conn, fsp, fname);
936                 SIVAL(params, 26, ea_size);
937         } else {
938                 SIVAL(params, 26, 0);
939         }
940
941         /* Send the required number of replies */
942         send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0, max_data_bytes);
943
944         return -1;
945 }
946
947 /*********************************************************
948  Routine to check if a given string matches exactly.
949  as a special case a mask of "." does NOT match. That
950  is required for correct wildcard semantics
951  Case can be significant or not.
952 **********************************************************/
953
954 static BOOL exact_match(connection_struct *conn, char *str, char *mask)
955 {
956         if (mask[0] == '.' && mask[1] == 0)
957                 return False;
958         if (conn->case_sensitive)
959                 return strcmp(str,mask)==0;
960         if (StrCaseCmp(str,mask) != 0) {
961                 return False;
962         }
963         if (dptr_has_wild(conn->dirptr)) {
964                 return False;
965         }
966         return True;
967 }
968
969 /****************************************************************************
970  Return the filetype for UNIX extensions.
971 ****************************************************************************/
972
973 static uint32 unix_filetype(mode_t mode)
974 {
975         if(S_ISREG(mode))
976                 return UNIX_TYPE_FILE;
977         else if(S_ISDIR(mode))
978                 return UNIX_TYPE_DIR;
979 #ifdef S_ISLNK
980         else if(S_ISLNK(mode))
981                 return UNIX_TYPE_SYMLINK;
982 #endif
983 #ifdef S_ISCHR
984         else if(S_ISCHR(mode))
985                 return UNIX_TYPE_CHARDEV;
986 #endif
987 #ifdef S_ISBLK
988         else if(S_ISBLK(mode))
989                 return UNIX_TYPE_BLKDEV;
990 #endif
991 #ifdef S_ISFIFO
992         else if(S_ISFIFO(mode))
993                 return UNIX_TYPE_FIFO;
994 #endif
995 #ifdef S_ISSOCK
996         else if(S_ISSOCK(mode))
997                 return UNIX_TYPE_SOCKET;
998 #endif
999
1000         DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
1001         return UNIX_TYPE_UNKNOWN;
1002 }
1003
1004 /****************************************************************************
1005  Map wire perms onto standard UNIX permissions. Obey share restrictions.
1006 ****************************************************************************/
1007
1008 enum perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR};
1009
1010 static NTSTATUS unix_perms_from_wire( connection_struct *conn,
1011                                 SMB_STRUCT_STAT *psbuf,
1012                                 uint32 perms,
1013                                 enum perm_type ptype,
1014                                 mode_t *ret_perms)
1015 {
1016         mode_t ret = 0;
1017
1018         if (perms == SMB_MODE_NO_CHANGE) {
1019                 if (!VALID_STAT(*psbuf)) {
1020                         return NT_STATUS_INVALID_PARAMETER;
1021                 } else {
1022                         *ret_perms = psbuf->st_mode;
1023                         return NT_STATUS_OK;
1024                 }
1025         }
1026
1027         ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
1028         ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
1029         ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
1030         ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
1031         ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
1032         ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
1033         ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
1034         ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
1035         ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
1036 #ifdef S_ISVTX
1037         ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
1038 #endif
1039 #ifdef S_ISGID
1040         ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
1041 #endif
1042 #ifdef S_ISUID
1043         ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
1044 #endif
1045
1046         switch (ptype) {
1047         case PERM_NEW_FILE:
1048                 /* Apply mode mask */
1049                 ret &= lp_create_mask(SNUM(conn));
1050                 /* Add in force bits */
1051                 ret |= lp_force_create_mode(SNUM(conn));
1052                 break;
1053         case PERM_NEW_DIR:
1054                 ret &= lp_dir_mask(SNUM(conn));
1055                 /* Add in force bits */
1056                 ret |= lp_force_dir_mode(SNUM(conn));
1057                 break;
1058         case PERM_EXISTING_FILE:
1059                 /* Apply mode mask */
1060                 ret &= lp_security_mask(SNUM(conn));
1061                 /* Add in force bits */
1062                 ret |= lp_force_security_mode(SNUM(conn));
1063                 break;
1064         case PERM_EXISTING_DIR:
1065                 /* Apply mode mask */
1066                 ret &= lp_dir_security_mask(SNUM(conn));
1067                 /* Add in force bits */
1068                 ret |= lp_force_dir_security_mode(SNUM(conn));
1069                 break;
1070         }
1071
1072         *ret_perms = ret;
1073         return NT_STATUS_OK;
1074 }
1075
1076 /****************************************************************************
1077  Get a level dependent lanman2 dir entry.
1078 ****************************************************************************/
1079
1080 static BOOL get_lanman2_dir_entry(connection_struct *conn,
1081                                   void *inbuf, char *outbuf,
1082                                  char *path_mask,uint32 dirtype,int info_level,
1083                                  int requires_resume_key,
1084                                  BOOL dont_descend,char **ppdata, 
1085                                  char *base_data, int space_remaining, 
1086                                  BOOL *out_of_space, BOOL *got_exact_match,
1087                                  int *last_entry_off, struct ea_list *name_list, TALLOC_CTX *ea_ctx)
1088 {
1089         const char *dname;
1090         BOOL found = False;
1091         SMB_STRUCT_STAT sbuf;
1092         pstring mask;
1093         pstring pathreal;
1094         pstring fname;
1095         char *p, *q, *pdata = *ppdata;
1096         uint32 reskey=0;
1097         long prev_dirpos=0;
1098         uint32 mode=0;
1099         SMB_OFF_T file_size = 0;
1100         SMB_BIG_UINT allocation_size = 0;
1101         uint32 len;
1102         struct timespec mdate_ts, adate_ts, create_date_ts;
1103         time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1104         char *nameptr;
1105         char *last_entry_ptr;
1106         BOOL was_8_3;
1107         uint32 nt_extmode; /* Used for NT connections instead of mode */
1108         BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
1109         BOOL check_mangled_names = lp_manglednames(conn->params);
1110
1111         *fname = 0;
1112         *out_of_space = False;
1113         *got_exact_match = False;
1114
1115         ZERO_STRUCT(mdate_ts);
1116         ZERO_STRUCT(adate_ts);
1117         ZERO_STRUCT(create_date_ts);
1118
1119         if (!conn->dirptr)
1120                 return(False);
1121
1122         p = strrchr_m(path_mask,'/');
1123         if(p != NULL) {
1124                 if(p[1] == '\0')
1125                         pstrcpy(mask,"*.*");
1126                 else
1127                         pstrcpy(mask, p+1);
1128         } else
1129                 pstrcpy(mask, path_mask);
1130
1131
1132         while (!found) {
1133                 BOOL got_match;
1134                 BOOL ms_dfs_link = False;
1135
1136                 /* Needed if we run out of space */
1137                 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
1138                 dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf);
1139
1140                 /*
1141                  * Due to bugs in NT client redirectors we are not using
1142                  * resume keys any more - set them to zero.
1143                  * Check out the related comments in findfirst/findnext.
1144                  * JRA.
1145                  */
1146
1147                 reskey = 0;
1148
1149                 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
1150                         (long)conn->dirptr,curr_dirpos));
1151       
1152                 if (!dname) 
1153                         return(False);
1154
1155                 pstrcpy(fname,dname);      
1156
1157                 if(!(got_match = *got_exact_match = exact_match(conn, fname, mask)))
1158                         got_match = mask_match(fname, mask, conn->case_sensitive);
1159
1160                 if(!got_match && check_mangled_names &&
1161                    !mangle_is_8_3(fname, False, conn->params)) {
1162
1163                         /*
1164                          * It turns out that NT matches wildcards against
1165                          * both long *and* short names. This may explain some
1166                          * of the wildcard wierdness from old DOS clients
1167                          * that some people have been seeing.... JRA.
1168                          */
1169
1170                         pstring newname;
1171                         pstrcpy( newname, fname);
1172                         mangle_map( newname, True, False, conn->params);
1173                         if(!(got_match = *got_exact_match = exact_match(conn, newname, mask)))
1174                                 got_match = mask_match(newname, mask, conn->case_sensitive);
1175                 }
1176
1177                 if(got_match) {
1178                         BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
1179                         if (dont_descend && !isdots)
1180                                 continue;
1181           
1182                         pstrcpy(pathreal,conn->dirpath);
1183                         if(needslash)
1184                                 pstrcat(pathreal,"/");
1185                         pstrcat(pathreal,dname);
1186
1187                         if (INFO_LEVEL_IS_UNIX(info_level)) {
1188                                 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
1189                                         DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
1190                                                 pathreal,strerror(errno)));
1191                                         continue;
1192                                 }
1193                         } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
1194
1195                                 /* Needed to show the msdfs symlinks as 
1196                                  * directories */
1197
1198                                 if(lp_host_msdfs() && 
1199                                    lp_msdfs_root(SNUM(conn)) &&
1200                                    ((ms_dfs_link = is_msdfs_link(NULL,conn, pathreal, NULL, NULL, &sbuf)) == True)) {
1201
1202                                         DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
1203                                         sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
1204
1205                                 } else {
1206
1207                                         DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
1208                                                 pathreal,strerror(errno)));
1209                                         continue;
1210                                 }
1211                         }
1212
1213                         if (ms_dfs_link) {
1214                                 mode = dos_mode_msdfs(conn,pathreal,&sbuf);
1215                         } else {
1216                                 mode = dos_mode(conn,pathreal,&sbuf);
1217                         }
1218
1219                         if (!dir_check_ftype(conn,mode,dirtype)) {
1220                                 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
1221                                 continue;
1222                         }
1223
1224                         if (!(mode & aDIR))
1225                                 file_size = get_file_size(sbuf);
1226                         allocation_size = get_allocation_size(conn,NULL,&sbuf);
1227
1228                         mdate_ts = get_mtimespec(&sbuf);
1229                         adate_ts = get_atimespec(&sbuf);
1230                         create_date_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1231
1232                         if (lp_dos_filetime_resolution(SNUM(conn))) {
1233                                 dos_filetime_timespec(&create_date_ts);
1234                                 dos_filetime_timespec(&mdate_ts);
1235                                 dos_filetime_timespec(&adate_ts);
1236                         }
1237
1238                         create_date = convert_timespec_to_time_t(create_date_ts);
1239                         mdate = convert_timespec_to_time_t(mdate_ts);
1240                         adate = convert_timespec_to_time_t(adate_ts);
1241                         
1242                         DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
1243           
1244                         found = True;
1245
1246                         dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
1247                 }
1248         }
1249
1250         mangle_map(fname,False,True,conn->params);
1251
1252         p = pdata;
1253         last_entry_ptr = p;
1254
1255         nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
1256
1257         switch (info_level) {
1258                 case SMB_FIND_INFO_STANDARD:
1259                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1260                         if(requires_resume_key) {
1261                                 SIVAL(p,0,reskey);
1262                                 p += 4;
1263                         }
1264                         srv_put_dos_date2(p,0,create_date);
1265                         srv_put_dos_date2(p,4,adate);
1266                         srv_put_dos_date2(p,8,mdate);
1267                         SIVAL(p,12,(uint32)file_size);
1268                         SIVAL(p,16,(uint32)allocation_size);
1269                         SSVAL(p,20,mode);
1270                         p += 23;
1271                         nameptr = p;
1272                         p += align_string(outbuf, p, 0);
1273                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1274                         if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1275                                 if (len > 2) {
1276                                         SCVAL(nameptr, -1, len - 2);
1277                                 } else {
1278                                         SCVAL(nameptr, -1, 0);
1279                                 }
1280                         } else {
1281                                 if (len > 1) {
1282                                         SCVAL(nameptr, -1, len - 1);
1283                                 } else {
1284                                         SCVAL(nameptr, -1, 0);
1285                                 }
1286                         }
1287                         p += len;
1288                         break;
1289
1290                 case SMB_FIND_EA_SIZE:
1291                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
1292                         if(requires_resume_key) {
1293                                 SIVAL(p,0,reskey);
1294                                 p += 4;
1295                         }
1296                         srv_put_dos_date2(p,0,create_date);
1297                         srv_put_dos_date2(p,4,adate);
1298                         srv_put_dos_date2(p,8,mdate);
1299                         SIVAL(p,12,(uint32)file_size);
1300                         SIVAL(p,16,(uint32)allocation_size);
1301                         SSVAL(p,20,mode);
1302                         {
1303                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1304                                 SIVAL(p,22,ea_size); /* Extended attributes */
1305                         }
1306                         p += 27;
1307                         nameptr = p - 1;
1308                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
1309                         if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1310                                 if (len > 2) {
1311                                         len -= 2;
1312                                 } else {
1313                                         len = 0;
1314                                 }
1315                         } else {
1316                                 if (len > 1) {
1317                                         len -= 1;
1318                                 } else {
1319                                         len = 0;
1320                                 }
1321                         }
1322                         SCVAL(nameptr,0,len);
1323                         p += len;
1324                         SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1325                         break;
1326
1327                 case SMB_FIND_EA_LIST:
1328                 {
1329                         struct ea_list *file_list = NULL;
1330                         size_t ea_len = 0;
1331
1332                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1333                         if (!name_list) {
1334                                 return False;
1335                         }
1336                         if(requires_resume_key) {
1337                                 SIVAL(p,0,reskey);
1338                                 p += 4;
1339                         }
1340                         srv_put_dos_date2(p,0,create_date);
1341                         srv_put_dos_date2(p,4,adate);
1342                         srv_put_dos_date2(p,8,mdate);
1343                         SIVAL(p,12,(uint32)file_size);
1344                         SIVAL(p,16,(uint32)allocation_size);
1345                         SSVAL(p,20,mode);
1346                         p += 22; /* p now points to the EA area. */
1347
1348                         file_list = get_ea_list_from_file(ea_ctx, conn, NULL, pathreal, &ea_len);
1349                         name_list = ea_list_union(name_list, file_list, &ea_len);
1350
1351                         /* We need to determine if this entry will fit in the space available. */
1352                         /* Max string size is 255 bytes. */
1353                         if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1354                                 /* Move the dirptr back to prev_dirpos */
1355                                 dptr_SeekDir(conn->dirptr, prev_dirpos);
1356                                 *out_of_space = True;
1357                                 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1358                                 return False; /* Not finished - just out of space */
1359                         }
1360
1361                         /* Push the ea_data followed by the name. */
1362                         p += fill_ea_buffer(ea_ctx, p, space_remaining, conn, name_list);
1363                         nameptr = p;
1364                         len = srvstr_push(outbuf, p + 1, fname, -1, STR_TERMINATE | STR_NOALIGN);
1365                         if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1366                                 if (len > 2) {
1367                                         len -= 2;
1368                                 } else {
1369                                         len = 0;
1370                                 }
1371                         } else {
1372                                 if (len > 1) {
1373                                         len -= 1;
1374                                 } else {
1375                                         len = 0;
1376                                 }
1377                         }
1378                         SCVAL(nameptr,0,len);
1379                         p += len + 1;
1380                         SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1381                         break;
1382                 }
1383
1384                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1385                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1386                         was_8_3 = mangle_is_8_3(fname, True, conn->params);
1387                         p += 4;
1388                         SIVAL(p,0,reskey); p += 4;
1389                         put_long_date_timespec(p,create_date_ts); p += 8;
1390                         put_long_date_timespec(p,adate_ts); p += 8;
1391                         put_long_date_timespec(p,mdate_ts); p += 8;
1392                         put_long_date_timespec(p,mdate_ts); p += 8;
1393                         SOFF_T(p,0,file_size); p += 8;
1394                         SOFF_T(p,0,allocation_size); p += 8;
1395                         SIVAL(p,0,nt_extmode); p += 4;
1396                         q = p; p += 4; /* q is placeholder for name length. */
1397                         {
1398                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1399                                 SIVAL(p,0,ea_size); /* Extended attributes */
1400                                 p += 4;
1401                         }
1402                         /* Clear the short name buffer. This is
1403                          * IMPORTANT as not doing so will trigger
1404                          * a Win2k client bug. JRA.
1405                          */
1406                         if (!was_8_3 && check_mangled_names) {
1407                                 pstring mangled_name;
1408                                 pstrcpy(mangled_name, fname);
1409                                 mangle_map(mangled_name,True,True,
1410                                            conn->params);
1411                                 mangled_name[12] = 0;
1412                                 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1413                                 if (len < 24) {
1414                                         memset(p + 2 + len,'\0',24 - len);
1415                                 }
1416                                 SSVAL(p, 0, len);
1417                         } else {
1418                                 memset(p,'\0',26);
1419                         }
1420                         p += 2 + 24;
1421                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1422                         SIVAL(q,0,len);
1423                         p += len;
1424                         SIVAL(p,0,0); /* Ensure any padding is null. */
1425                         len = PTR_DIFF(p, pdata);
1426                         len = (len + 3) & ~3;
1427                         SIVAL(pdata,0,len);
1428                         p = pdata + len;
1429                         break;
1430
1431                 case SMB_FIND_FILE_DIRECTORY_INFO:
1432                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1433                         p += 4;
1434                         SIVAL(p,0,reskey); p += 4;
1435                         put_long_date_timespec(p,create_date_ts); p += 8;
1436                         put_long_date_timespec(p,adate_ts); p += 8;
1437                         put_long_date_timespec(p,mdate_ts); p += 8;
1438                         put_long_date_timespec(p,mdate_ts); p += 8;
1439                         SOFF_T(p,0,file_size); p += 8;
1440                         SOFF_T(p,0,allocation_size); p += 8;
1441                         SIVAL(p,0,nt_extmode); p += 4;
1442                         len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII);
1443                         SIVAL(p,0,len);
1444                         p += 4 + len;
1445                         SIVAL(p,0,0); /* Ensure any padding is null. */
1446                         len = PTR_DIFF(p, pdata);
1447                         len = (len + 3) & ~3;
1448                         SIVAL(pdata,0,len);
1449                         p = pdata + len;
1450                         break;
1451       
1452                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1453                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1454                         p += 4;
1455                         SIVAL(p,0,reskey); p += 4;
1456                         put_long_date_timespec(p,create_date_ts); p += 8;
1457                         put_long_date_timespec(p,adate_ts); p += 8;
1458                         put_long_date_timespec(p,mdate_ts); p += 8;
1459                         put_long_date_timespec(p,mdate_ts); p += 8;
1460                         SOFF_T(p,0,file_size); p += 8;
1461                         SOFF_T(p,0,allocation_size); p += 8;
1462                         SIVAL(p,0,nt_extmode); p += 4;
1463                         q = p; p += 4; /* q is placeholder for name length. */
1464                         {
1465                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1466                                 SIVAL(p,0,ea_size); /* Extended attributes */
1467                                 p +=4;
1468                         }
1469                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1470                         SIVAL(q, 0, len);
1471                         p += len;
1472
1473                         SIVAL(p,0,0); /* Ensure any padding is null. */
1474                         len = PTR_DIFF(p, pdata);
1475                         len = (len + 3) & ~3;
1476                         SIVAL(pdata,0,len);
1477                         p = pdata + len;
1478                         break;
1479
1480                 case SMB_FIND_FILE_NAMES_INFO:
1481                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1482                         p += 4;
1483                         SIVAL(p,0,reskey); p += 4;
1484                         p += 4;
1485                         /* this must *not* be null terminated or w2k gets in a loop trying to set an
1486                            acl on a dir (tridge) */
1487                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1488                         SIVAL(p, -4, len);
1489                         p += len;
1490                         SIVAL(p,0,0); /* Ensure any padding is null. */
1491                         len = PTR_DIFF(p, pdata);
1492                         len = (len + 3) & ~3;
1493                         SIVAL(pdata,0,len);
1494                         p = pdata + len;
1495                         break;
1496
1497                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1498                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1499                         p += 4;
1500                         SIVAL(p,0,reskey); p += 4;
1501                         put_long_date_timespec(p,create_date_ts); p += 8;
1502                         put_long_date_timespec(p,adate_ts); p += 8;
1503                         put_long_date_timespec(p,mdate_ts); p += 8;
1504                         put_long_date_timespec(p,mdate_ts); p += 8;
1505                         SOFF_T(p,0,file_size); p += 8;
1506                         SOFF_T(p,0,allocation_size); p += 8;
1507                         SIVAL(p,0,nt_extmode); p += 4;
1508                         q = p; p += 4; /* q is placeholder for name length. */
1509                         {
1510                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1511                                 SIVAL(p,0,ea_size); /* Extended attributes */
1512                                 p +=4;
1513                         }
1514                         SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1515                         SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
1516                         SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
1517                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1518                         SIVAL(q, 0, len);
1519                         p += len; 
1520                         SIVAL(p,0,0); /* Ensure any padding is null. */
1521                         len = PTR_DIFF(p, pdata);
1522                         len = (len + 3) & ~3;
1523                         SIVAL(pdata,0,len);
1524                         p = pdata + len;
1525                         break;
1526
1527                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1528                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1529                         was_8_3 = mangle_is_8_3(fname, True, conn->params);
1530                         p += 4;
1531                         SIVAL(p,0,reskey); p += 4;
1532                         put_long_date_timespec(p,create_date_ts); p += 8;
1533                         put_long_date_timespec(p,adate_ts); p += 8;
1534                         put_long_date_timespec(p,mdate_ts); p += 8;
1535                         put_long_date_timespec(p,mdate_ts); p += 8;
1536                         SOFF_T(p,0,file_size); p += 8;
1537                         SOFF_T(p,0,allocation_size); p += 8;
1538                         SIVAL(p,0,nt_extmode); p += 4;
1539                         q = p; p += 4; /* q is placeholder for name length */
1540                         {
1541                                 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1542                                 SIVAL(p,0,ea_size); /* Extended attributes */
1543                                 p +=4;
1544                         }
1545                         /* Clear the short name buffer. This is
1546                          * IMPORTANT as not doing so will trigger
1547                          * a Win2k client bug. JRA.
1548                          */
1549                         if (!was_8_3 && check_mangled_names) {
1550                                 pstring mangled_name;
1551                                 pstrcpy(mangled_name, fname);
1552                                 mangle_map(mangled_name,True,True,
1553                                            conn->params);
1554                                 mangled_name[12] = 0;
1555                                 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1556                                 SSVAL(p, 0, len);
1557                                 if (len < 24) {
1558                                         memset(p + 2 + len,'\0',24 - len);
1559                                 }
1560                                 SSVAL(p, 0, len);
1561                         } else {
1562                                 memset(p,'\0',26);
1563                         }
1564                         p += 26;
1565                         SSVAL(p,0,0); p += 2; /* Reserved ? */
1566                         SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
1567                         SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
1568                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1569                         SIVAL(q,0,len);
1570                         p += len;
1571                         SIVAL(p,0,0); /* Ensure any padding is null. */
1572                         len = PTR_DIFF(p, pdata);
1573                         len = (len + 3) & ~3;
1574                         SIVAL(pdata,0,len);
1575                         p = pdata + len;
1576                         break;
1577
1578                 /* CIFS UNIX Extension. */
1579
1580                 case SMB_FIND_FILE_UNIX:
1581                         DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1582                         p+= 4;
1583                         SIVAL(p,0,reskey); p+= 4;    /* Used for continuing search. */
1584
1585                         /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1586                         SOFF_T(p,0,get_file_size(sbuf));             /* File size 64 Bit */
1587                         p+= 8;
1588
1589                         SOFF_T(p,0,get_allocation_size(conn,NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
1590                         p+= 8;
1591
1592                         put_long_date_timespec(p,get_ctimespec(&sbuf));       /* Inode change Time 64 Bit */
1593                         put_long_date_timespec(p+8,get_atimespec(&sbuf));     /* Last access time 64 Bit */
1594                         put_long_date_timespec(p+16,get_mtimespec(&sbuf));    /* Last modification time 64 Bit */
1595                         p+= 24;
1596
1597                         SIVAL(p,0,sbuf.st_uid);               /* user id for the owner */
1598                         SIVAL(p,4,0);
1599                         p+= 8;
1600
1601                         SIVAL(p,0,sbuf.st_gid);               /* group id of owner */
1602                         SIVAL(p,4,0);
1603                         p+= 8;
1604
1605                         SIVAL(p,0,unix_filetype(sbuf.st_mode));
1606                         p+= 4;
1607
1608                         SIVAL(p,0,unix_dev_major(sbuf.st_rdev));   /* Major device number if type is device */
1609                         SIVAL(p,4,0);
1610                         p+= 8;
1611
1612                         SIVAL(p,0,unix_dev_minor(sbuf.st_rdev));   /* Minor device number if type is device */
1613                         SIVAL(p,4,0);
1614                         p+= 8;
1615
1616                         SINO_T_VAL(p,0,(SMB_INO_T)sbuf.st_ino);   /* inode number */
1617                         p+= 8;
1618
1619                         SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode));     /* Standard UNIX file permissions */
1620                         SIVAL(p,4,0);
1621                         p+= 8;
1622
1623                         SIVAL(p,0,sbuf.st_nlink);             /* number of hard links */
1624                         SIVAL(p,4,0);
1625                         p+= 8;
1626
1627                         len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1628                         p += len;
1629                         SIVAL(p,0,0); /* Ensure any padding is null. */
1630
1631                         len = PTR_DIFF(p, pdata);
1632                         len = (len + 3) & ~3;
1633                         SIVAL(pdata,0,len);     /* Offset from this structure to the beginning of the next one */
1634                         p = pdata + len;
1635                         /* End of SMB_QUERY_FILE_UNIX_BASIC */
1636
1637                         break;
1638
1639                 default:      
1640                         return(False);
1641         }
1642
1643
1644         if (PTR_DIFF(p,pdata) > space_remaining) {
1645                 /* Move the dirptr back to prev_dirpos */
1646                 dptr_SeekDir(conn->dirptr, prev_dirpos);
1647                 *out_of_space = True;
1648                 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1649                 return False; /* Not finished - just out of space */
1650         }
1651
1652         /* Setup the last entry pointer, as an offset from base_data */
1653         *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1654         /* Advance the data pointer to the next slot */
1655         *ppdata = p;
1656
1657         return(found);
1658 }
1659
1660 /****************************************************************************
1661  Reply to a TRANS2_FINDFIRST.
1662 ****************************************************************************/
1663
1664 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,  
1665                                 char **pparams, int total_params, char **ppdata, int total_data,
1666                                 unsigned int max_data_bytes)
1667 {
1668         /* We must be careful here that we don't return more than the
1669                 allowed number of data bytes. If this means returning fewer than
1670                 maxentries then so be it. We assume that the redirector has
1671                 enough room for the fixed number of parameter bytes it has
1672                 requested. */
1673         char *params = *pparams;
1674         char *pdata = *ppdata;
1675         uint32 dirtype;
1676         int maxentries;
1677         uint16 findfirst_flags;
1678         BOOL close_after_first;
1679         BOOL close_if_end;
1680         BOOL requires_resume_key;
1681         int info_level;
1682         pstring directory;
1683         pstring mask;
1684         char *p;
1685         int last_entry_off=0;
1686         int dptr_num = -1;
1687         int numentries = 0;
1688         int i;
1689         BOOL finished = False;
1690         BOOL dont_descend = False;
1691         BOOL out_of_space = False;
1692         int space_remaining;
1693         BOOL mask_contains_wcard = False;
1694         SMB_STRUCT_STAT sbuf;
1695         TALLOC_CTX *ea_ctx = NULL;
1696         struct ea_list *ea_list = NULL;
1697         NTSTATUS ntstatus = NT_STATUS_OK;
1698
1699         if (total_params < 13) {
1700                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1701         }
1702
1703         dirtype = SVAL(params,0);
1704         maxentries = SVAL(params,2);
1705         findfirst_flags = SVAL(params,4);
1706         close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1707         close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1708         requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1709         info_level = SVAL(params,6);
1710
1711         *directory = *mask = 0;
1712
1713         DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
1714 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1715                 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1716                 info_level, max_data_bytes));
1717
1718         if (!maxentries) {
1719                 /* W2K3 seems to treat zero as 1. */
1720                 maxentries = 1;
1721         }
1722  
1723         switch (info_level) {
1724                 case SMB_FIND_INFO_STANDARD:
1725                 case SMB_FIND_EA_SIZE:
1726                 case SMB_FIND_EA_LIST:
1727                 case SMB_FIND_FILE_DIRECTORY_INFO:
1728                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1729                 case SMB_FIND_FILE_NAMES_INFO:
1730                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1731                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1732                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1733                         break;
1734                 case SMB_FIND_FILE_UNIX:
1735                         if (!lp_unix_extensions()) {
1736                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
1737                         }
1738                         break;
1739                 default:
1740                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
1741         }
1742
1743         srvstr_get_path_wcard(inbuf, directory, params+12, sizeof(directory), total_params - 12, STR_TERMINATE, &ntstatus, &mask_contains_wcard);
1744         if (!NT_STATUS_IS_OK(ntstatus)) {
1745                 return ERROR_NT(ntstatus);
1746         }
1747
1748         RESOLVE_DFSPATH_WCARD(directory, conn, inbuf, outbuf);
1749
1750         ntstatus = unix_convert(conn, directory, True, NULL, &sbuf);
1751         if (!NT_STATUS_IS_OK(ntstatus)) {
1752                 return ERROR_NT(ntstatus);
1753         }
1754         ntstatus = check_name(conn, directory);
1755         if (!NT_STATUS_IS_OK(ntstatus)) {
1756                 return ERROR_NT(ntstatus);
1757         }
1758
1759         p = strrchr_m(directory,'/');
1760         if(p == NULL) {
1761                 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1762                 if((directory[0] == '.') && (directory[1] == '\0')) {
1763                         pstrcpy(mask,"*");
1764                         mask_contains_wcard = True;
1765                 } else {
1766                         pstrcpy(mask,directory);
1767                 }
1768                 pstrcpy(directory,"./");
1769         } else {
1770                 pstrcpy(mask,p+1);
1771                 *p = 0;
1772         }
1773
1774         DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
1775
1776         if (info_level == SMB_FIND_EA_LIST) {
1777                 uint32 ea_size;
1778
1779                 if (total_data < 4) {
1780                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1781                 }
1782
1783                 ea_size = IVAL(pdata,0);
1784                 if (ea_size != total_data) {
1785                         DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
1786 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
1787                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1788                 }
1789
1790                 if (!lp_ea_support(SNUM(conn))) {
1791                         return ERROR_DOS(ERRDOS,ERReasnotsupported);
1792                 }
1793                                                                                                                                                         
1794                 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
1795                         return ERROR_NT(NT_STATUS_NO_MEMORY);
1796                 }
1797
1798                 /* Pull out the list of names. */
1799                 ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
1800                 if (!ea_list) {
1801                         talloc_destroy(ea_ctx);
1802                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1803                 }
1804         }
1805
1806         *ppdata = (char *)SMB_REALLOC(
1807                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1808         if(*ppdata == NULL ) {
1809                 talloc_destroy(ea_ctx);
1810                 return ERROR_NT(NT_STATUS_NO_MEMORY);
1811         }
1812         pdata = *ppdata;
1813
1814         /* Realloc the params space */
1815         *pparams = (char *)SMB_REALLOC(*pparams, 10);
1816         if (*pparams == NULL) {
1817                 talloc_destroy(ea_ctx);
1818                 return ERROR_NT(NT_STATUS_NO_MEMORY);
1819         }
1820         params = *pparams;
1821
1822         /* Save the wildcard match and attribs we are using on this directory - 
1823                 needed as lanman2 assumes these are being saved between calls */
1824
1825         ntstatus = dptr_create(conn,
1826                                 directory,
1827                                 False,
1828                                 True,
1829                                 SVAL(inbuf,smb_pid),
1830                                 mask,
1831                                 mask_contains_wcard,
1832                                 dirtype,
1833                                 &conn->dirptr);
1834
1835         if (!NT_STATUS_IS_OK(ntstatus)) {
1836                 talloc_destroy(ea_ctx);
1837                 return ERROR_NT(ntstatus);
1838         }
1839
1840         dptr_num = dptr_dnum(conn->dirptr);
1841         DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
1842
1843         /* We don't need to check for VOL here as this is returned by 
1844                 a different TRANS2 call. */
1845   
1846         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1847         if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1848                 dont_descend = True;
1849     
1850         p = pdata;
1851         space_remaining = max_data_bytes;
1852         out_of_space = False;
1853
1854         for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1855                 BOOL got_exact_match = False;
1856
1857                 /* this is a heuristic to avoid seeking the dirptr except when 
1858                         absolutely necessary. It allows for a filename of about 40 chars */
1859                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1860                         out_of_space = True;
1861                         finished = False;
1862                 } else {
1863                         finished = !get_lanman2_dir_entry(conn,
1864                                         inbuf, outbuf,
1865                                         mask,dirtype,info_level,
1866                                         requires_resume_key,dont_descend,
1867                                         &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1868                                         &last_entry_off, ea_list, ea_ctx);
1869                 }
1870
1871                 if (finished && out_of_space)
1872                         finished = False;
1873
1874                 if (!finished && !out_of_space)
1875                         numentries++;
1876
1877                 /*
1878                  * As an optimisation if we know we aren't looking
1879                  * for a wildcard name (ie. the name matches the wildcard exactly)
1880                  * then we can finish on any (first) match.
1881                  * This speeds up large directory searches. JRA.
1882                  */
1883
1884                 if(got_exact_match)
1885                         finished = True;
1886
1887                 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1888         }
1889   
1890         talloc_destroy(ea_ctx);
1891
1892         /* Check if we can close the dirptr */
1893         if(close_after_first || (finished && close_if_end)) {
1894                 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1895                 dptr_close(&dptr_num);
1896         }
1897
1898         /* 
1899          * If there are no matching entries we must return ERRDOS/ERRbadfile - 
1900          * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
1901          * the protocol level is less than NT1. Tested with smbclient. JRA.
1902          * This should fix the OS/2 client bug #2335.
1903          */
1904
1905         if(numentries == 0) {
1906                 dptr_close(&dptr_num);
1907                 if (Protocol < PROTOCOL_NT1) {
1908                         return ERROR_DOS(ERRDOS,ERRnofiles);
1909                 } else {
1910                         return ERROR_BOTH(NT_STATUS_NO_SUCH_FILE,ERRDOS,ERRbadfile);
1911                 }
1912         }
1913
1914         /* At this point pdata points to numentries directory entries. */
1915
1916         /* Set up the return parameter block */
1917         SSVAL(params,0,dptr_num);
1918         SSVAL(params,2,numentries);
1919         SSVAL(params,4,finished);
1920         SSVAL(params,6,0); /* Never an EA error */
1921         SSVAL(params,8,last_entry_off);
1922
1923         send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata), max_data_bytes);
1924
1925         if ((! *directory) && dptr_path(dptr_num))
1926                 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1927
1928         DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1929                 smb_fn_name(CVAL(inbuf,smb_com)), 
1930                 mask, directory, dirtype, numentries ) );
1931
1932         /* 
1933          * Force a name mangle here to ensure that the
1934          * mask as an 8.3 name is top of the mangled cache.
1935          * The reasons for this are subtle. Don't remove
1936          * this code unless you know what you are doing
1937          * (see PR#13758). JRA.
1938          */
1939
1940         if(!mangle_is_8_3_wildcards( mask, False, conn->params))
1941                 mangle_map(mask, True, True, conn->params);
1942
1943         return(-1);
1944 }
1945
1946 /****************************************************************************
1947  Reply to a TRANS2_FINDNEXT.
1948 ****************************************************************************/
1949
1950 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1951                                         char **pparams, int total_params, char **ppdata, int total_data,
1952                                         unsigned int max_data_bytes)
1953 {
1954         /* We must be careful here that we don't return more than the
1955                 allowed number of data bytes. If this means returning fewer than
1956                 maxentries then so be it. We assume that the redirector has
1957                 enough room for the fixed number of parameter bytes it has
1958                 requested. */
1959         char *params = *pparams;
1960         char *pdata = *ppdata;
1961         int dptr_num;
1962         int maxentries;
1963         uint16 info_level;
1964         uint32 resume_key;
1965         uint16 findnext_flags;
1966         BOOL close_after_request;
1967         BOOL close_if_end;
1968         BOOL requires_resume_key;
1969         BOOL continue_bit;
1970         BOOL mask_contains_wcard = False;
1971         pstring resume_name;
1972         pstring mask;
1973         pstring directory;
1974         char *p;
1975         uint16 dirtype;
1976         int numentries = 0;
1977         int i, last_entry_off=0;
1978         BOOL finished = False;
1979         BOOL dont_descend = False;
1980         BOOL out_of_space = False;
1981         int space_remaining;
1982         TALLOC_CTX *ea_ctx = NULL;
1983         struct ea_list *ea_list = NULL;
1984         NTSTATUS ntstatus = NT_STATUS_OK;
1985
1986         if (total_params < 13) {
1987                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1988         }
1989
1990         dptr_num = SVAL(params,0);
1991         maxentries = SVAL(params,2);
1992         info_level = SVAL(params,4);
1993         resume_key = IVAL(params,6);
1994         findnext_flags = SVAL(params,10);
1995         close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
1996         close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1997         requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1998         continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
1999
2000         *mask = *directory = *resume_name = 0;
2001
2002         srvstr_get_path_wcard(inbuf, resume_name, params+12, sizeof(resume_name), total_params - 12, STR_TERMINATE, &ntstatus, &mask_contains_wcard);
2003         if (!NT_STATUS_IS_OK(ntstatus)) {
2004                 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
2005                    complain (it thinks we're asking for the directory above the shared
2006                    path or an invalid name). Catch this as the resume name is only compared, never used in
2007                    a file access. JRA. */
2008                 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) {
2009                         pstrcpy(resume_name, "..");
2010                 } else if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_NAME_INVALID)) {
2011                         pstrcpy(resume_name, ".");
2012                 } else {
2013                         return ERROR_NT(ntstatus);
2014                 }
2015         }
2016
2017         DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
2018 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
2019 resume_key = %d resume name = %s continue=%d level = %d\n",
2020                 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end, 
2021                 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
2022
2023         if (!maxentries) {
2024                 /* W2K3 seems to treat zero as 1. */
2025                 maxentries = 1;
2026         }
2027
2028         switch (info_level) {
2029                 case SMB_FIND_INFO_STANDARD:
2030                 case SMB_FIND_EA_SIZE:
2031                 case SMB_FIND_EA_LIST:
2032                 case SMB_FIND_FILE_DIRECTORY_INFO:
2033                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2034                 case SMB_FIND_FILE_NAMES_INFO:
2035                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2036                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2037                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2038                         break;
2039                 case SMB_FIND_FILE_UNIX:
2040                         if (!lp_unix_extensions()) {
2041                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2042                         }
2043                         break;
2044                 default:
2045                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2046         }
2047
2048         if (info_level == SMB_FIND_EA_LIST) {
2049                 uint32 ea_size;
2050
2051                 if (total_data < 4) {
2052                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2053                 }
2054
2055                 ea_size = IVAL(pdata,0);
2056                 if (ea_size != total_data) {
2057                         DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2058 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2059                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2060                 }
2061                                                                                                                                                      
2062                 if (!lp_ea_support(SNUM(conn))) {
2063                         return ERROR_DOS(ERRDOS,ERReasnotsupported);
2064                 }
2065                                                                                                                                                      
2066                 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
2067                         return ERROR_NT(NT_STATUS_NO_MEMORY);
2068                 }
2069
2070                 /* Pull out the list of names. */
2071                 ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
2072                 if (!ea_list) {
2073                         talloc_destroy(ea_ctx);
2074                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2075                 }
2076         }
2077
2078         *ppdata = (char *)SMB_REALLOC(
2079                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2080         if(*ppdata == NULL) {
2081                 talloc_destroy(ea_ctx);
2082                 return ERROR_NT(NT_STATUS_NO_MEMORY);
2083         }
2084
2085         pdata = *ppdata;
2086
2087         /* Realloc the params space */
2088         *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
2089         if(*pparams == NULL ) {
2090                 talloc_destroy(ea_ctx);
2091                 return ERROR_NT(NT_STATUS_NO_MEMORY);
2092         }
2093
2094         params = *pparams;
2095
2096         /* Check that the dptr is valid */
2097         if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
2098                 talloc_destroy(ea_ctx);
2099                 return ERROR_DOS(ERRDOS,ERRnofiles);
2100         }
2101
2102         string_set(&conn->dirpath,dptr_path(dptr_num));
2103
2104         /* Get the wildcard mask from the dptr */
2105         if((p = dptr_wcard(dptr_num))== NULL) {
2106                 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
2107                 talloc_destroy(ea_ctx);
2108                 return ERROR_DOS(ERRDOS,ERRnofiles);
2109         }
2110
2111         pstrcpy(mask, p);
2112         pstrcpy(directory,conn->dirpath);
2113
2114         /* Get the attr mask from the dptr */
2115         dirtype = dptr_attr(dptr_num);
2116
2117         DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2118                 dptr_num, mask, dirtype, 
2119                 (long)conn->dirptr,
2120                 dptr_TellDir(conn->dirptr)));
2121
2122         /* We don't need to check for VOL here as this is returned by 
2123                 a different TRANS2 call. */
2124
2125         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
2126         if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2127                 dont_descend = True;
2128     
2129         p = pdata;
2130         space_remaining = max_data_bytes;
2131         out_of_space = False;
2132
2133         /* 
2134          * Seek to the correct position. We no longer use the resume key but
2135          * depend on the last file name instead.
2136          */
2137
2138         if(*resume_name && !continue_bit) {
2139                 SMB_STRUCT_STAT st;
2140
2141                 long current_pos = 0;
2142                 /*
2143                  * Remember, mangle_map is called by
2144                  * get_lanman2_dir_entry(), so the resume name
2145                  * could be mangled. Ensure we check the unmangled name.
2146                  */
2147
2148                 if (mangle_is_mangled(resume_name, conn->params)) {
2149                         mangle_check_cache(resume_name, sizeof(resume_name)-1,
2150                                            conn->params);
2151                 }
2152
2153                 /*
2154                  * Fix for NT redirector problem triggered by resume key indexes
2155                  * changing between directory scans. We now return a resume key of 0
2156                  * and instead look for the filename to continue from (also given
2157                  * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2158                  * findfirst/findnext (as is usual) then the directory pointer
2159                  * should already be at the correct place.
2160                  */
2161
2162                 finished = !dptr_SearchDir(conn->dirptr, resume_name, &current_pos, &st);
2163         } /* end if resume_name && !continue_bit */
2164
2165         for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
2166                 BOOL got_exact_match = False;
2167
2168                 /* this is a heuristic to avoid seeking the dirptr except when 
2169                         absolutely necessary. It allows for a filename of about 40 chars */
2170                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2171                         out_of_space = True;
2172                         finished = False;
2173                 } else {
2174                         finished = !get_lanman2_dir_entry(conn,
2175                                                 inbuf, outbuf,
2176                                                 mask,dirtype,info_level,
2177                                                 requires_resume_key,dont_descend,
2178                                                 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
2179                                                 &last_entry_off, ea_list, ea_ctx);
2180                 }
2181
2182                 if (finished && out_of_space)
2183                         finished = False;
2184
2185                 if (!finished && !out_of_space)
2186                         numentries++;
2187
2188                 /*
2189                  * As an optimisation if we know we aren't looking
2190                  * for a wildcard name (ie. the name matches the wildcard exactly)
2191                  * then we can finish on any (first) match.
2192                  * This speeds up large directory searches. JRA.
2193                  */
2194
2195                 if(got_exact_match)
2196                         finished = True;
2197
2198                 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2199         }
2200   
2201         talloc_destroy(ea_ctx);
2202
2203         /* Check if we can close the dirptr */
2204         if(close_after_request || (finished && close_if_end)) {
2205                 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2206                 dptr_close(&dptr_num); /* This frees up the saved mask */
2207         }
2208
2209         /* Set up the return parameter block */
2210         SSVAL(params,0,numentries);
2211         SSVAL(params,2,finished);
2212         SSVAL(params,4,0); /* Never an EA error */
2213         SSVAL(params,6,last_entry_off);
2214
2215         send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata), max_data_bytes);
2216
2217         if ((! *directory) && dptr_path(dptr_num))
2218                 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
2219
2220         DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2221                 smb_fn_name(CVAL(inbuf,smb_com)), 
2222                 mask, directory, dirtype, numentries ) );
2223
2224         return(-1);
2225 }
2226
2227 /****************************************************************************
2228  Reply to a TRANS2_QFSINFO (query filesystem info).
2229 ****************************************************************************/
2230
2231 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2232                                         char **pparams, int total_params, char **ppdata, int total_data,
2233                                         unsigned int max_data_bytes)
2234 {
2235         char *pdata = *ppdata;
2236         char *params = *pparams;
2237         uint16 info_level;
2238         int data_len, len;
2239         SMB_STRUCT_STAT st;
2240         char *vname = volume_label(SNUM(conn));
2241         int snum = SNUM(conn);
2242         char *fstype = lp_fstype(SNUM(conn));
2243         int quota_flag = 0;
2244
2245         if (total_params < 2) {
2246                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2247         }
2248
2249         info_level = SVAL(params,0);
2250
2251         DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
2252
2253         if(SMB_VFS_STAT(conn,".",&st)!=0) {
2254                 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
2255                 return ERROR_DOS(ERRSRV,ERRinvdevice);
2256         }
2257
2258         *ppdata = (char *)SMB_REALLOC(
2259                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2260         if (*ppdata == NULL ) {
2261                 return ERROR_NT(NT_STATUS_NO_MEMORY);
2262         }
2263
2264         pdata = *ppdata;
2265         memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2266
2267         switch (info_level) {
2268                 case SMB_INFO_ALLOCATION:
2269                 {
2270                         SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2271                         data_len = 18;
2272                         if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2273                                 return(UNIXERROR(ERRHRD,ERRgeneral));
2274                         }
2275
2276                         block_size = lp_block_size(snum);
2277                         if (bsize < block_size) {
2278                                 SMB_BIG_UINT factor = block_size/bsize;
2279                                 bsize = block_size;
2280                                 dsize /= factor;
2281                                 dfree /= factor;
2282                         }
2283                         if (bsize > block_size) {
2284                                 SMB_BIG_UINT factor = bsize/block_size;
2285                                 bsize = block_size;
2286                                 dsize *= factor;
2287                                 dfree *= factor;
2288                         }
2289                         bytes_per_sector = 512;
2290                         sectors_per_unit = bsize/bytes_per_sector;
2291
2292                         DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2293 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2294                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2295
2296                         SIVAL(pdata,l1_idFileSystem,st.st_dev);
2297                         SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2298                         SIVAL(pdata,l1_cUnit,dsize);
2299                         SIVAL(pdata,l1_cUnitAvail,dfree);
2300                         SSVAL(pdata,l1_cbSector,bytes_per_sector);
2301                         break;
2302                 }
2303
2304                 case SMB_INFO_VOLUME:
2305                         /* Return volume name */
2306                         /* 
2307                          * Add volume serial number - hash of a combination of
2308                          * the called hostname and the service name.
2309                          */
2310                         SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2311                         /*
2312                          * Win2k3 and previous mess this up by sending a name length
2313                          * one byte short. I believe only older clients (OS/2 Win9x) use
2314                          * this call so try fixing this by adding a terminating null to
2315                          * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2316                          */
2317                         len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN|STR_TERMINATE);
2318                         SCVAL(pdata,l2_vol_cch,len);
2319                         data_len = l2_vol_szVolLabel + len;
2320                         DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
2321                                 (unsigned)st.st_ctime, len, vname));
2322                         break;
2323
2324                 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2325                 case SMB_FS_ATTRIBUTE_INFORMATION:
2326
2327
2328 #if defined(HAVE_SYS_QUOTAS)
2329                         quota_flag = FILE_VOLUME_QUOTAS;
2330 #endif
2331
2332                         SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2333                                 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
2334                                 quota_flag); /* FS ATTRIBUTES */
2335
2336                         SIVAL(pdata,4,255); /* Max filename component length */
2337                         /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2338                                 and will think we can't do long filenames */
2339                         len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
2340                         SIVAL(pdata,8,len);
2341                         data_len = 12 + len;
2342                         break;
2343
2344                 case SMB_QUERY_FS_LABEL_INFO:
2345                 case SMB_FS_LABEL_INFORMATION:
2346                         len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
2347                         data_len = 4 + len;
2348                         SIVAL(pdata,0,len);
2349                         break;
2350
2351                 case SMB_QUERY_FS_VOLUME_INFO:      
2352                 case SMB_FS_VOLUME_INFORMATION:
2353
2354                         /* 
2355                          * Add volume serial number - hash of a combination of
2356                          * the called hostname and the service name.
2357                          */
2358                         SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ 
2359                                 (str_checksum(get_local_machine_name())<<16));
2360
2361                         len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
2362                         SIVAL(pdata,12,len);
2363                         data_len = 18+len;
2364                         DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", 
2365                                 (int)strlen(vname),vname, lp_servicename(snum)));
2366                         break;
2367
2368                 case SMB_QUERY_FS_SIZE_INFO:
2369                 case SMB_FS_SIZE_INFORMATION:
2370                 {
2371                         SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2372                         data_len = 24;
2373                         if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2374                                 return(UNIXERROR(ERRHRD,ERRgeneral));
2375                         }
2376                         block_size = lp_block_size(snum);
2377                         if (bsize < block_size) {
2378                                 SMB_BIG_UINT factor = block_size/bsize;
2379                                 bsize = block_size;
2380                                 dsize /= factor;
2381                                 dfree /= factor;
2382                         }
2383                         if (bsize > block_size) {
2384                                 SMB_BIG_UINT factor = bsize/block_size;
2385                                 bsize = block_size;
2386                                 dsize *= factor;
2387                                 dfree *= factor;
2388                         }
2389                         bytes_per_sector = 512;
2390                         sectors_per_unit = bsize/bytes_per_sector;
2391                         DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2392 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2393                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2394                         SBIG_UINT(pdata,0,dsize);
2395                         SBIG_UINT(pdata,8,dfree);
2396                         SIVAL(pdata,16,sectors_per_unit);
2397                         SIVAL(pdata,20,bytes_per_sector);
2398                         break;
2399                 }
2400
2401                 case SMB_FS_FULL_SIZE_INFORMATION:
2402                 {
2403                         SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2404                         data_len = 32;
2405                         if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2406                                 return(UNIXERROR(ERRHRD,ERRgeneral));
2407                         }
2408                         block_size = lp_block_size(snum);
2409                         if (bsize < block_size) {
2410                                 SMB_BIG_UINT factor = block_size/bsize;
2411                                 bsize = block_size;
2412                                 dsize /= factor;
2413                                 dfree /= factor;
2414                         }
2415                         if (bsize > block_size) {
2416                                 SMB_BIG_UINT factor = bsize/block_size;
2417                                 bsize = block_size;
2418                                 dsize *= factor;
2419                                 dfree *= factor;
2420                         }
2421                         bytes_per_sector = 512;
2422                         sectors_per_unit = bsize/bytes_per_sector;
2423                         DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2424 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2425                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2426                         SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2427                         SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2428                         SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2429                         SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2430                         SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2431                         break;
2432                 }
2433
2434                 case SMB_QUERY_FS_DEVICE_INFO:
2435                 case SMB_FS_DEVICE_INFORMATION:
2436                         data_len = 8;
2437                         SIVAL(pdata,0,0); /* dev type */
2438                         SIVAL(pdata,4,0); /* characteristics */
2439                         break;
2440
2441 #ifdef HAVE_SYS_QUOTAS
2442                 case SMB_FS_QUOTA_INFORMATION:
2443                 /* 
2444                  * what we have to send --metze:
2445                  *
2446                  * Unknown1:            24 NULL bytes
2447                  * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
2448                  * Hard Quota Limit:    8 bytes seems like SMB_BIG_UINT or so
2449                  * Quota Flags:         2 byte :
2450                  * Unknown3:            6 NULL bytes
2451                  *
2452                  * 48 bytes total
2453                  * 
2454                  * details for Quota Flags:
2455                  * 
2456                  * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2457                  * 0x0010 Log Warn:  log if the user exceeds his Soft Quota
2458                  * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2459                  * 0x0001 Enable Quotas: enable quota for this fs
2460                  *
2461                  */
2462                 {
2463                         /* we need to fake up a fsp here,
2464                          * because its not send in this call
2465                          */
2466                         files_struct fsp;
2467                         SMB_NTQUOTA_STRUCT quotas;
2468                         
2469                         ZERO_STRUCT(fsp);
2470                         ZERO_STRUCT(quotas);
2471                         
2472                         fsp.conn = conn;
2473                         fsp.fnum = -1;
2474                         
2475                         /* access check */
2476                         if (current_user.ut.uid != 0) {
2477                                 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2478                                         lp_servicename(SNUM(conn)),conn->user));
2479                                 return ERROR_DOS(ERRDOS,ERRnoaccess);
2480                         }
2481                         
2482                         if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
2483                                 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2484                                 return ERROR_DOS(ERRSRV,ERRerror);
2485                         }
2486
2487                         data_len = 48;
2488
2489                         DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));          
2490                 
2491                         /* Unknown1 24 NULL bytes*/
2492                         SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
2493                         SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
2494                         SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
2495                 
2496                         /* Default Soft Quota 8 bytes */
2497                         SBIG_UINT(pdata,24,quotas.softlim);
2498
2499                         /* Default Hard Quota 8 bytes */
2500                         SBIG_UINT(pdata,32,quotas.hardlim);
2501         
2502                         /* Quota flag 2 bytes */
2503                         SSVAL(pdata,40,quotas.qflags);
2504                 
2505                         /* Unknown3 6 NULL bytes */
2506                         SSVAL(pdata,42,0);
2507                         SIVAL(pdata,44,0);
2508                         
2509                         break;
2510                 }
2511 #endif /* HAVE_SYS_QUOTAS */
2512                 case SMB_FS_OBJECTID_INFORMATION:
2513                         data_len = 64;
2514                         break;
2515
2516                 /*
2517                  * Query the version and capabilities of the CIFS UNIX extensions
2518                  * in use.
2519                  */
2520
2521                 case SMB_QUERY_CIFS_UNIX_INFO:
2522                         if (!lp_unix_extensions()) {
2523                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2524                         }
2525                         data_len = 12;
2526                         SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2527                         SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2528                         /* We have POSIX ACLs, pathname and locking capability. */
2529                         SBIG_UINT(pdata,4,((SMB_BIG_UINT)(
2530                                         CIFS_UNIX_POSIX_ACLS_CAP|
2531                                         CIFS_UNIX_POSIX_PATHNAMES_CAP|
2532                                         CIFS_UNIX_FCNTL_LOCKS_CAP|
2533                                         CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)));
2534                         break;
2535
2536                 case SMB_QUERY_POSIX_FS_INFO:
2537                 {
2538                         int rc;
2539                         vfs_statvfs_struct svfs;
2540
2541                         if (!lp_unix_extensions()) {
2542                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2543                         }
2544
2545                         rc = SMB_VFS_STATVFS(conn, ".", &svfs);
2546
2547                         if (!rc) {
2548                                 data_len = 56;
2549                                 SIVAL(pdata,0,svfs.OptimalTransferSize);
2550                                 SIVAL(pdata,4,svfs.BlockSize);
2551                                 SBIG_UINT(pdata,8,svfs.TotalBlocks);
2552                                 SBIG_UINT(pdata,16,svfs.BlocksAvail);
2553                                 SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
2554                                 SBIG_UINT(pdata,32,svfs.TotalFileNodes);
2555                                 SBIG_UINT(pdata,40,svfs.FreeFileNodes);
2556                                 SBIG_UINT(pdata,48,svfs.FsIdentifier);
2557                                 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
2558 #ifdef EOPNOTSUPP
2559                         } else if (rc == EOPNOTSUPP) {
2560                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2561 #endif /* EOPNOTSUPP */
2562                         } else {
2563                                 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2564                                 return ERROR_DOS(ERRSRV,ERRerror);
2565                         }
2566                         break;
2567                 }
2568
2569                 case SMB_MAC_QUERY_FS_INFO:
2570                         /*
2571                          * Thursby MAC extension... ONLY on NTFS filesystems
2572                          * once we do streams then we don't need this
2573                          */
2574                         if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2575                                 data_len = 88;
2576                                 SIVAL(pdata,84,0x100); /* Don't support mac... */
2577                                 break;
2578                         }
2579                         /* drop through */
2580                 default:
2581                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2582         }
2583
2584
2585         send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len, max_data_bytes);
2586
2587         DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
2588
2589         return -1;
2590 }
2591
2592 /****************************************************************************
2593  Reply to a TRANS2_SETFSINFO (set filesystem info).
2594 ****************************************************************************/
2595
2596 static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2597                                         char **pparams, int total_params, char **ppdata, int total_data,
2598                                         unsigned int max_data_bytes)
2599 {
2600         char *pdata = *ppdata;
2601         char *params = *pparams;
2602         uint16 info_level;
2603         int outsize;
2604
2605         DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn))));
2606
2607         /*  */
2608         if (total_params < 4) {
2609                 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2610                         total_params));
2611                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2612         }
2613
2614         info_level = SVAL(params,2);
2615
2616         switch(info_level) {
2617                 case SMB_SET_CIFS_UNIX_INFO:
2618                         {
2619                                 uint16 client_unix_major;
2620                                 uint16 client_unix_minor;
2621                                 uint32 client_unix_cap_low;
2622                                 uint32 client_unix_cap_high;
2623
2624                                 if (!lp_unix_extensions()) {
2625                                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2626                                 }
2627
2628                                 /* There should be 12 bytes of capabilities set. */
2629                                 if (total_data < 8) {
2630                                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2631                                 }
2632                                 client_unix_major = SVAL(pdata,0);
2633                                 client_unix_minor = SVAL(pdata,2);
2634                                 client_unix_cap_low = IVAL(pdata,4);
2635                                 client_unix_cap_high = IVAL(pdata,8);
2636                                 /* Just print these values for now. */
2637                                 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
2638 cap_low = 0x%x, cap_high = 0x%x\n",
2639                                         (unsigned int)client_unix_major,
2640                                         (unsigned int)client_unix_minor,
2641                                         (unsigned int)client_unix_cap_low,
2642                                         (unsigned int)client_unix_cap_high ));
2643
2644                                 /* Here is where we must switch to posix pathname processing... */
2645                                 if (client_unix_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2646                                         lp_set_posix_pathnames();
2647                                         mangle_change_to_posix();
2648                                 }
2649
2650                                 if ((client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
2651                                     !(client_unix_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
2652                                         /* Client that knows how to do posix locks,
2653                                          * but not posix open/mkdir operations. Set a
2654                                          * default type for read/write checks. */
2655
2656                                         lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
2657
2658                                 }
2659                                 break;
2660                         }
2661                 case SMB_FS_QUOTA_INFORMATION:
2662                         {
2663                                 files_struct *fsp = NULL;
2664                                 SMB_NTQUOTA_STRUCT quotas;
2665         
2666                                 ZERO_STRUCT(quotas);
2667
2668                                 /* access check */
2669                                 if ((current_user.ut.uid != 0)||!CAN_WRITE(conn)) {
2670                                         DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2671                                                 lp_servicename(SNUM(conn)),conn->user));
2672                                         return ERROR_DOS(ERRSRV,ERRaccess);
2673                                 }
2674
2675                                 /* note: normaly there're 48 bytes,
2676                                  * but we didn't use the last 6 bytes for now 
2677                                  * --metze 
2678                                  */
2679                                 fsp = file_fsp(params,0);
2680                                 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2681                                         DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2682                                         return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2683                                 }
2684
2685                                 if (total_data < 42) {
2686                                         DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2687                                                 total_data));
2688                                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2689                                 }
2690                         
2691                                 /* unknown_1 24 NULL bytes in pdata*/
2692                 
2693                                 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2694                                 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2695 #ifdef LARGE_SMB_OFF_T
2696                                 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2697 #else /* LARGE_SMB_OFF_T */
2698                                 if ((IVAL(pdata,28) != 0)&&
2699                                         ((quotas.softlim != 0xFFFFFFFF)||
2700                                         (IVAL(pdata,28)!=0xFFFFFFFF))) {
2701                                         /* more than 32 bits? */
2702                                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2703                                 }
2704 #endif /* LARGE_SMB_OFF_T */
2705                 
2706                                 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2707                                 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2708 #ifdef LARGE_SMB_OFF_T
2709                                 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2710 #else /* LARGE_SMB_OFF_T */
2711                                 if ((IVAL(pdata,36) != 0)&&
2712                                         ((quotas.hardlim != 0xFFFFFFFF)||
2713                                         (IVAL(pdata,36)!=0xFFFFFFFF))) {
2714                                         /* more than 32 bits? */
2715                                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2716                                 }
2717 #endif /* LARGE_SMB_OFF_T */
2718                 
2719                                 /* quota_flags 2 bytes **/
2720                                 quotas.qflags = SVAL(pdata,40);
2721                 
2722                                 /* unknown_2 6 NULL bytes follow*/
2723                 
2724                                 /* now set the quotas */
2725                                 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
2726                                         DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2727                                         return ERROR_DOS(ERRSRV,ERRerror);
2728                                 }
2729                         
2730                                 break;
2731                         }
2732                 default:
2733                         DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2734                                 info_level));
2735                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2736                         break;
2737         }
2738
2739         /* 
2740          * sending this reply works fine, 
2741          * but I'm not sure it's the same 
2742          * like windows do...
2743          * --metze
2744          */ 
2745         outsize = set_message(outbuf,10,0,True);
2746
2747         return outsize;
2748 }
2749
2750 #if defined(HAVE_POSIX_ACLS)
2751 /****************************************************************************
2752  Utility function to count the number of entries in a POSIX acl.
2753 ****************************************************************************/
2754
2755 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
2756 {
2757         unsigned int ace_count = 0;
2758         int entry_id = SMB_ACL_FIRST_ENTRY;
2759         SMB_ACL_ENTRY_T entry;
2760
2761         while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2762                 /* get_next... */
2763                 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2764                         entry_id = SMB_ACL_NEXT_ENTRY;
2765                 }
2766                 ace_count++;
2767         }
2768         return ace_count;
2769 }
2770
2771 /****************************************************************************
2772  Utility function to marshall a POSIX acl into wire format.
2773 ****************************************************************************/
2774
2775 static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
2776 {
2777         int entry_id = SMB_ACL_FIRST_ENTRY;
2778         SMB_ACL_ENTRY_T entry;
2779
2780         while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2781                 SMB_ACL_TAG_T tagtype;
2782                 SMB_ACL_PERMSET_T permset;
2783                 unsigned char perms = 0;
2784                 unsigned int own_grp;
2785
2786                 /* get_next... */
2787                 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2788                         entry_id = SMB_ACL_NEXT_ENTRY;
2789                 }
2790
2791                 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
2792                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2793                         return False;
2794                 }
2795
2796                 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
2797                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2798                         return False;
2799                 }
2800
2801                 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
2802                 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
2803                 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
2804
2805                 SCVAL(pdata,1,perms);
2806
2807                 switch (tagtype) {
2808                         case SMB_ACL_USER_OBJ:
2809                                 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
2810                                 own_grp = (unsigned int)pst->st_uid;
2811                                 SIVAL(pdata,2,own_grp);
2812                                 SIVAL(pdata,6,0);
2813                                 break;
2814                         case SMB_ACL_USER:
2815                                 {
2816                                         uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2817                                         if (!puid) {
2818                                                 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2819                                         }
2820                                         own_grp = (unsigned int)*puid;
2821                                         SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
2822                                         SCVAL(pdata,0,SMB_POSIX_ACL_USER);
2823                                         SIVAL(pdata,2,own_grp);
2824                                         SIVAL(pdata,6,0);
2825                                         break;
2826                                 }
2827                         case SMB_ACL_GROUP_OBJ:
2828                                 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
2829                                 own_grp = (unsigned int)pst->st_gid;
2830                                 SIVAL(pdata,2,own_grp);
2831                                 SIVAL(pdata,6,0);
2832                                 break;
2833                         case SMB_ACL_GROUP:
2834                                 {
2835                                         gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2836                                         if (!pgid) {
2837                                                 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2838                                         }
2839                                         own_grp = (unsigned int)*pgid;
2840                                         SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
2841                                         SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
2842                                         SIVAL(pdata,2,own_grp);
2843                                         SIVAL(pdata,6,0);
2844                                         break;
2845                                 }
2846                         case SMB_ACL_MASK:
2847                                 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
2848                                 SIVAL(pdata,2,0xFFFFFFFF);
2849                                 SIVAL(pdata,6,0xFFFFFFFF);
2850                                 break;
2851                         case SMB_ACL_OTHER:
2852                                 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
2853                                 SIVAL(pdata,2,0xFFFFFFFF);
2854                                 SIVAL(pdata,6,0xFFFFFFFF);
2855                                 break;
2856                         default:
2857                                 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
2858                                 return False;
2859                 }
2860                 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
2861         }
2862
2863         return True;
2864 }
2865 #endif
2866
2867 /****************************************************************************
2868  Store the FILE_UNIX_BASIC info.
2869 ****************************************************************************/
2870
2871 static char *store_file_unix_basic(connection_struct *conn,
2872                                 char *pdata,
2873                                 files_struct *fsp,
2874                                 SMB_STRUCT_STAT *psbuf)
2875 {
2876         DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
2877         DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_mode));
2878
2879         SOFF_T(pdata,0,get_file_size(*psbuf));             /* File size 64 Bit */
2880         pdata += 8;
2881
2882         SOFF_T(pdata,0,get_allocation_size(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
2883         pdata += 8;
2884
2885         put_long_date_timespec(pdata,get_ctimespec(psbuf));       /* Change Time 64 Bit */
2886         put_long_date_timespec(pdata+8,get_atimespec(psbuf));     /* Last access time 64 Bit */
2887         put_long_date_timespec(pdata+16,get_mtimespec(psbuf));    /* Last modification time 64 Bit */
2888         pdata += 24;
2889
2890         SIVAL(pdata,0,psbuf->st_uid);               /* user id for the owner */
2891         SIVAL(pdata,4,0);
2892         pdata += 8;
2893
2894         SIVAL(pdata,0,psbuf->st_gid);               /* group id of owner */
2895         SIVAL(pdata,4,0);
2896         pdata += 8;
2897
2898         SIVAL(pdata,0,unix_filetype(psbuf->st_mode));
2899         pdata += 4;
2900
2901         SIVAL(pdata,0,unix_dev_major(psbuf->st_rdev));   /* Major device number if type is device */
2902         SIVAL(pdata,4,0);
2903         pdata += 8;
2904
2905         SIVAL(pdata,0,unix_dev_minor(psbuf->st_rdev));   /* Minor device number if type is device */
2906         SIVAL(pdata,4,0);
2907         pdata += 8;
2908
2909         SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ino);   /* inode number */
2910         pdata += 8;
2911                                 
2912         SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_mode));     /* Standard UNIX file permissions */
2913         SIVAL(pdata,4,0);
2914         pdata += 8;
2915
2916         SIVAL(pdata,0,psbuf->st_nlink);             /* number of hard links */
2917         SIVAL(pdata,4,0);
2918         pdata += 8;
2919
2920         return pdata;
2921 }
2922
2923 /****************************************************************************
2924  Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2925  file name or file id).
2926 ****************************************************************************/
2927
2928 static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2929                                         unsigned int tran_call,
2930                                         char **pparams, int total_params, char **ppdata, int total_data,
2931                                         unsigned int max_data_bytes)
2932 {
2933         char *params = *pparams;
2934         char *pdata = *ppdata;
2935         uint16 info_level;
2936         int mode=0;
2937         int nlink;
2938         SMB_OFF_T file_size=0;
2939         SMB_BIG_UINT allocation_size=0;
2940         unsigned int data_size = 0;
2941         unsigned int param_size = 2;
2942         SMB_STRUCT_STAT sbuf;
2943         pstring fname, dos_fname;
2944         char *fullpathname;
2945         char *base_name;
2946         char *p;
2947         SMB_OFF_T pos = 0;
2948         BOOL delete_pending = False;
2949         int len;
2950         time_t create_time, mtime, atime;
2951         struct timespec create_time_ts, mtime_ts, atime_ts;
2952         files_struct *fsp = NULL;
2953         TALLOC_CTX *data_ctx = NULL;
2954         struct ea_list *ea_list = NULL;
2955         uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2956         char *lock_data = NULL;
2957
2958         if (!params)
2959                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2960
2961         ZERO_STRUCT(sbuf);
2962
2963         if (tran_call == TRANSACT2_QFILEINFO) {
2964                 if (total_params < 4) {
2965                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2966                 }
2967
2968                 fsp = file_fsp(params,0);
2969                 info_level = SVAL(params,2);
2970
2971                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
2972
2973                 if(fsp && (fsp->fake_file_handle)) {
2974                         /*
2975                          * This is actually for the QUOTA_FAKE_FILE --metze
2976                          */
2977                                                 
2978                         pstrcpy(fname, fsp->fsp_name);
2979                         /* We know this name is ok, it's already passed the checks. */
2980                         
2981                 } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
2982                         /*
2983                          * This is actually a QFILEINFO on a directory
2984                          * handle (returned from an NT SMB). NT5.0 seems
2985                          * to do this call. JRA.
2986                          */
2987                         /* We know this name is ok, it's already passed the checks. */
2988                         pstrcpy(fname, fsp->fsp_name);
2989                   
2990                         if (INFO_LEVEL_IS_UNIX(info_level)) {
2991                                 /* Always do lstat for UNIX calls. */
2992                                 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2993                                         DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2994                                         return UNIXERROR(ERRDOS,ERRbadpath);
2995                                 }
2996                         } else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
2997                                 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2998                                 return UNIXERROR(ERRDOS,ERRbadpath);
2999                         }
3000
3001                         delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
3002                 } else {
3003                         /*
3004                          * Original code - this is an open file.
3005                          */
3006                         CHECK_FSP(fsp,conn);
3007
3008                         pstrcpy(fname, fsp->fsp_name);
3009                         if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) {
3010                                 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
3011                                 return(UNIXERROR(ERRDOS,ERRbadfid));
3012                         }
3013                         pos = fsp->fh->position_information;
3014                         delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
3015                         access_mask = fsp->access_mask;
3016                 }
3017         } else {
3018                 NTSTATUS status = NT_STATUS_OK;
3019
3020                 /* qpathinfo */
3021                 if (total_params < 7) {
3022                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3023                 }
3024
3025                 info_level = SVAL(params,0);
3026
3027                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
3028
3029                 srvstr_get_path(inbuf, fname, &params[6], sizeof(fname), total_params - 6, STR_TERMINATE, &status);
3030                 if (!NT_STATUS_IS_OK(status)) {
3031                         return ERROR_NT(status);
3032                 }
3033
3034                 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
3035
3036                 status = unix_convert(conn, fname, False, NULL, &sbuf);
3037                 if (!NT_STATUS_IS_OK(status)) {
3038                         return ERROR_NT(status);
3039                 }
3040                 status = check_name(conn, fname);
3041                 if (!NT_STATUS_IS_OK(status)) {
3042                         DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,nt_errstr(status)));
3043                         return ERROR_NT(status);
3044                 }
3045
3046                 if (INFO_LEVEL_IS_UNIX(info_level)) {
3047                         /* Always do lstat for UNIX calls. */
3048                         if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
3049                                 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
3050                                 return UNIXERROR(ERRDOS,ERRbadpath);
3051                         }
3052                 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
3053                         DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
3054                         return UNIXERROR(ERRDOS,ERRbadpath);
3055                 }
3056
3057                 delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
3058                 if (delete_pending) {
3059                         return ERROR_NT(NT_STATUS_DELETE_PENDING);
3060                 }
3061         }
3062
3063         nlink = sbuf.st_nlink;
3064
3065         if ((nlink > 0) && S_ISDIR(sbuf.st_mode)) {
3066                 /* NTFS does not seem to count ".." */
3067                 nlink -= 1;
3068         }
3069
3070         if ((nlink > 0) && delete_pending) {
3071                 nlink -= 1;
3072         }
3073
3074         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
3075                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
3076         }
3077
3078         DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
3079                 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
3080
3081         p = strrchr_m(fname,'/'); 
3082         if (!p)
3083                 base_name = fname;
3084         else
3085                 base_name = p+1;
3086
3087         mode = dos_mode(conn,fname,&sbuf);
3088         if (!mode)
3089                 mode = FILE_ATTRIBUTE_NORMAL;
3090
3091         fullpathname = fname;
3092         if (!(mode & aDIR))
3093                 file_size = get_file_size(sbuf);
3094
3095         /* Pull out any data sent here before we realloc. */
3096         switch (info_level) {
3097                 case SMB_INFO_QUERY_EAS_FROM_LIST:
3098                 {
3099                         /* Pull any EA list from the data portion. */
3100                         uint32 ea_size;
3101
3102                         if (total_data < 4) {
3103                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3104                         }
3105                         ea_size = IVAL(pdata,0);
3106
3107                         if (total_data > 0 && ea_size != total_data) {
3108                                 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
3109 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
3110                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3111                         }
3112
3113                         if (!lp_ea_support(SNUM(conn))) {
3114                                 return ERROR_DOS(ERRDOS,ERReasnotsupported);
3115                         }
3116
3117                         if ((data_ctx = talloc_init("ea_list")) == NULL) {
3118                                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3119                         }
3120
3121                         /* Pull out the list of names. */
3122                         ea_list = read_ea_name_list(data_ctx, pdata + 4, ea_size - 4);
3123                         if (!ea_list) {
3124                                 talloc_destroy(data_ctx);
3125                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3126                         }
3127                         break;
3128                 }
3129
3130                 case SMB_QUERY_POSIX_LOCK:
3131                 {
3132                         if (fsp == NULL || fsp->fh->fd == -1) {
3133                                 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
3134                         }
3135
3136                         if (total_data != POSIX_LOCK_DATA_SIZE) {
3137                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3138                         }
3139
3140                         if ((data_ctx = talloc_init("lock_request")) == NULL) {
3141                                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3142                         }
3143
3144                         /* Copy the lock range data. */
3145                         lock_data = (char *)talloc_memdup(
3146                                 data_ctx, pdata, total_data);
3147                         if (!lock_data) {
3148                                 talloc_destroy(data_ctx);
3149                                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3150                         }
3151                 }
3152                 default:
3153                         break;
3154         }
3155
3156         *pparams = (char *)SMB_REALLOC(*pparams,2);
3157         if (*pparams == NULL) {
3158                 talloc_destroy(data_ctx);
3159                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3160         }
3161         params = *pparams;
3162         SSVAL(params,0,0);
3163         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
3164         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 
3165         if (*ppdata == NULL ) {
3166                 talloc_destroy(data_ctx);
3167                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3168         }
3169         pdata = *ppdata;
3170
3171         create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
3172         mtime_ts = get_mtimespec(&sbuf);
3173         atime_ts = get_atimespec(&sbuf);
3174
3175         allocation_size = get_allocation_size(conn,fsp,&sbuf);
3176
3177         if (fsp) {
3178                 if (fsp->pending_modtime) {
3179                         /* the pending modtime overrides the current modtime */
3180                         mtime_ts.tv_sec = fsp->pending_modtime;
3181                         mtime_ts.tv_nsec = 0;
3182                 }
3183         } else {
3184                 /* Do we have this path open ? */
3185                 files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino);
3186                 if (fsp1 && fsp1->pending_modtime) {
3187                         /* the pending modtime overrides the current modtime */
3188                         mtime_ts.tv_sec = fsp1->pending_modtime;
3189                         mtime_ts.tv_nsec = 0;
3190                 }
3191                 if (fsp1 && fsp1->initial_allocation_size) {
3192                         allocation_size = get_allocation_size(conn, fsp1, &sbuf);
3193                 }
3194         }
3195
3196         if (lp_dos_filetime_resolution(SNUM(conn))) {
3197                 dos_filetime_timespec(&create_time_ts);
3198                 dos_filetime_timespec(&mtime_ts);
3199                 dos_filetime_timespec(&atime_ts);
3200         }
3201
3202         create_time = convert_timespec_to_time_t(create_time_ts);
3203         mtime = convert_timespec_to_time_t(mtime_ts);
3204         atime = convert_timespec_to_time_t(atime_ts);
3205
3206         /* NT expects the name to be in an exact form of the *full*
3207            filename. See the trans2 torture test */
3208         if (strequal(base_name,".")) {
3209                 pstrcpy(dos_fname, "\\");
3210         } else {
3211                 pstr_sprintf(dos_fname, "\\%s", fname);
3212                 string_replace(dos_fname, '/', '\\');
3213         }
3214
3215         switch (info_level) {
3216                 case SMB_INFO_STANDARD:
3217                         DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
3218                         data_size = 22;
3219                         srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
3220                         srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
3221                         srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
3222                         SIVAL(pdata,l1_cbFile,(uint32)file_size);
3223                         SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
3224                         SSVAL(pdata,l1_attrFile,mode);
3225                         break;
3226
3227                 case SMB_INFO_QUERY_EA_SIZE:
3228                 {
3229                         unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3230                         DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
3231                         data_size = 26;
3232                         srv_put_dos_date2(pdata,0,create_time);
3233                         srv_put_dos_date2(pdata,4,atime);
3234                         srv_put_dos_date2(pdata,8,mtime); /* write time */
3235                         SIVAL(pdata,12,(uint32)file_size);
3236                         SIVAL(pdata,16,(uint32)allocation_size);
3237                         SSVAL(pdata,20,mode);
3238                         SIVAL(pdata,22,ea_size);
3239                         break;
3240                 }
3241
3242                 case SMB_INFO_IS_NAME_VALID:
3243                         DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
3244                         if (tran_call == TRANSACT2_QFILEINFO) {
3245                                 /* os/2 needs this ? really ?*/      
3246                                 return ERROR_DOS(ERRDOS,ERRbadfunc); 
3247                         }
3248                         data_size = 0;
3249                         param_size = 0;
3250                         break;
3251                         
3252                 case SMB_INFO_QUERY_EAS_FROM_LIST:
3253                 {
3254                         size_t total_ea_len = 0;
3255                         struct ea_list *ea_file_list = NULL;
3256
3257                         DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
3258
3259                         ea_file_list = get_ea_list_from_file(data_ctx, conn, fsp, fname, &total_ea_len);
3260                         ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
3261
3262                         if (!ea_list || (total_ea_len > data_size)) {
3263                                 talloc_destroy(data_ctx);
3264                                 data_size = 4;
3265                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
3266                                 break;
3267                         }
3268
3269                         data_size = fill_ea_buffer(data_ctx, pdata, data_size, conn, ea_list);
3270                         talloc_destroy(data_ctx);
3271                         break;
3272                 }
3273
3274                 case SMB_INFO_QUERY_ALL_EAS:
3275                 {
3276                         /* We have data_size bytes to put EA's into. */
3277                         size_t total_ea_len = 0;
3278
3279                         DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
3280
3281                         data_ctx = talloc_init("ea_ctx");
3282                         if (!data_ctx) {
3283                                 return ERROR_NT(NT_STATUS_NO_MEMORY);
3284                         }
3285
3286                         ea_list = get_ea_list_from_file(data_ctx, conn, fsp, fname, &total_ea_len);
3287                         if (!ea_list || (total_ea_len > data_size)) {
3288                                 talloc_destroy(data_ctx);
3289                                 data_size = 4;
3290                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
3291                                 break;
3292                         }
3293
3294                         data_size = fill_ea_buffer(data_ctx, pdata, data_size, conn, ea_list);
3295                         talloc_destroy(data_ctx);
3296                         break;
3297                 }
3298
3299                 case SMB_FILE_BASIC_INFORMATION:
3300                 case SMB_QUERY_FILE_BASIC_INFO:
3301
3302                         if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
3303                                 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
3304                                 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
3305                         } else {
3306                                 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
3307                                 data_size = 40;
3308                                 SIVAL(pdata,36,0);
3309                         }
3310                         put_long_date_timespec(pdata,create_time_ts);
3311                         put_long_date_timespec(pdata+8,atime_ts);
3312                         put_long_date_timespec(pdata+16,mtime_ts); /* write time */
3313                         put_long_date_timespec(pdata+24,mtime_ts); /* change time */
3314                         SIVAL(pdata,32,mode);
3315
3316                         DEBUG(5,("SMB_QFBI - "));
3317                         DEBUG(5,("create: %s ", ctime(&create_time)));
3318                         DEBUG(5,("access: %s ", ctime(&atime)));
3319                         DEBUG(5,("write: %s ", ctime(&mtime)));
3320                         DEBUG(5,("change: %s ", ctime(&mtime)));
3321                         DEBUG(5,("mode: %x\n", mode));
3322                         break;
3323
3324                 case SMB_FILE_STANDARD_INFORMATION:
3325                 case SMB_QUERY_FILE_STANDARD_INFO:
3326
3327                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
3328                         data_size = 24;
3329                         SOFF_T(pdata,0,allocation_size);
3330                         SOFF_T(pdata,8,file_size);
3331                         SIVAL(pdata,16,nlink);
3332                         SCVAL(pdata,20,delete_pending?1:0);
3333                         SCVAL(pdata,21,(mode&aDIR)?1:0);
3334                         SSVAL(pdata,22,0); /* Padding. */
3335                         break;
3336
3337                 case SMB_FILE_EA_INFORMATION:
3338                 case SMB_QUERY_FILE_EA_INFO:
3339                 {
3340                         unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3341                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
3342                         data_size = 4;
3343                         SIVAL(pdata,0,ea_size);
3344                         break;
3345                 }
3346
3347                 /* Get the 8.3 name - used if NT SMB was negotiated. */
3348                 case SMB_QUERY_FILE_ALT_NAME_INFO:
3349                 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
3350                 {
3351                         pstring short_name;
3352
3353                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
3354                         pstrcpy(short_name,base_name);
3355                         /* Mangle if not already 8.3 */
3356                         if(!mangle_is_8_3(short_name, True, conn->params)) {
3357                                 mangle_map(short_name,True,True,conn->params);
3358                         }
3359                         len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
3360                         data_size = 4 + len;
3361                         SIVAL(pdata,0,len);
3362                         break;
3363                 }
3364
3365                 case SMB_QUERY_FILE_NAME_INFO:
3366                         /*
3367                           this must be *exactly* right for ACLs on mapped drives to work
3368                          */
3369                         len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
3370                         DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
3371                         data_size = 4 + len;
3372                         SIVAL(pdata,0,len);
3373                         break;
3374
3375                 case SMB_FILE_ALLOCATION_INFORMATION:
3376                 case SMB_QUERY_FILE_ALLOCATION_INFO:
3377                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
3378                         data_size = 8;
3379                         SOFF_T(pdata,0,allocation_size);
3380                         break;
3381
3382                 case SMB_FILE_END_OF_FILE_INFORMATION:
3383                 case SMB_QUERY_FILE_END_OF_FILEINFO:
3384                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
3385                         data_size = 8;
3386                         SOFF_T(pdata,0,file_size);
3387                         break;
3388
3389                 case SMB_QUERY_FILE_ALL_INFO:
3390                 case SMB_FILE_ALL_INFORMATION:
3391                 {
3392                         unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3393                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
3394                         put_long_date_timespec(pdata,create_time_ts);
3395                         put_long_date_timespec(pdata+8,atime_ts);
3396                         put_long_date_timespec(pdata+16,mtime_ts); /* write time */
3397                         put_long_date_timespec(pdata+24,mtime_ts); /* change time */
3398                         SIVAL(pdata,32,mode);
3399                         SIVAL(pdata,36,0); /* padding. */
3400                         pdata += 40;
3401                         SOFF_T(pdata,0,allocation_size);
3402                         SOFF_T(pdata,8,file_size);
3403                         SIVAL(pdata,16,nlink);
3404                         SCVAL(pdata,20,delete_pending);
3405                         SCVAL(pdata,21,(mode&aDIR)?1:0);
3406                         SSVAL(pdata,22,0);
3407                         pdata += 24;
3408                         SIVAL(pdata,0,ea_size);
3409                         pdata += 4; /* EA info */
3410                         len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
3411                         SIVAL(pdata,0,len);
3412                         pdata += 4 + len;
3413                         data_size = PTR_DIFF(pdata,(*ppdata));
3414                         break;
3415                 }
3416                 case SMB_FILE_INTERNAL_INFORMATION:
3417                         /* This should be an index number - looks like
3418                            dev/ino to me :-) 
3419
3420                            I think this causes us to fail the IFSKIT
3421                            BasicFileInformationTest. -tpot */
3422
3423                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
3424                         SIVAL(pdata,0,sbuf.st_ino); /* FileIndexLow */
3425                         SIVAL(pdata,4,sbuf.st_dev); /* FileIndexHigh */
3426                         data_size = 8;
3427                         break;
3428
3429                 case SMB_FILE_ACCESS_INFORMATION:
3430                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
3431                         SIVAL(pdata,0,access_mask);
3432                         data_size = 4;
3433                         break;
3434
3435                 case SMB_FILE_NAME_INFORMATION:
3436                         /* Pathname with leading '\'. */
3437                         {
3438                                 size_t byte_len;
3439                                 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
3440                                 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
3441                                 SIVAL(pdata,0,byte_len);
3442                                 data_size = 4 + byte_len;
3443                                 break;
3444                         }
3445
3446                 case SMB_FILE_DISPOSITION_INFORMATION:
3447                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
3448                         data_size = 1;
3449                         SCVAL(pdata,0,delete_pending);
3450                         break;
3451
3452                 case SMB_FILE_POSITION_INFORMATION:
3453                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
3454                         data_size = 8;
3455                         SOFF_T(pdata,0,pos);
3456                         break;
3457
3458                 case SMB_FILE_MODE_INFORMATION:
3459                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
3460                         SIVAL(pdata,0,mode);
3461                         data_size = 4;
3462                         break;
3463
3464                 case SMB_FILE_ALIGNMENT_INFORMATION:
3465                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
3466                         SIVAL(pdata,0,0); /* No alignment needed. */
3467                         data_size = 4;
3468                         break;
3469
3470 #if 0
3471                 /*
3472                  * NT4 server just returns "invalid query" to this - if we try to answer
3473                  * it then NTws gets a BSOD! (tridge).
3474                  * W2K seems to want this. JRA.
3475                  */
3476                 case SMB_QUERY_FILE_STREAM_INFO:
3477 #endif
3478                 case SMB_FILE_STREAM_INFORMATION:
3479                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
3480                         if (mode & aDIR) {
3481                                 data_size = 0;
3482                         } else {
3483                                 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", (size_t)0xE, False);
3484                                 SIVAL(pdata,0,0); /* ??? */
3485                                 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
3486                                 SOFF_T(pdata,8,file_size);
3487                                 SIVAL(pdata,16,allocation_size);
3488                                 SIVAL(pdata,20,0); /* ??? */
3489                                 data_size = 24 + byte_len;
3490                         }
3491                         break;
3492
3493                 case SMB_QUERY_COMPRESSION_INFO:
3494                 case SMB_FILE_COMPRESSION_INFORMATION:
3495                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
3496                         SOFF_T(pdata,0,file_size);
3497                         SIVAL(pdata,8,0); /* ??? */
3498                         SIVAL(pdata,12,0); /* ??? */
3499                         data_size = 16;
3500                         break;
3501
3502                 case SMB_FILE_NETWORK_OPEN_INFORMATION:
3503                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
3504                         put_long_date_timespec(pdata,create_time_ts);
3505                         put_long_date_timespec(pdata+8,atime_ts);
3506                         put_long_date_timespec(pdata+16,mtime_ts); /* write time */
3507                         put_long_date_timespec(pdata+24,mtime_ts); /* change time */
3508                         SIVAL(pdata,32,allocation_size);
3509                         SOFF_T(pdata,40,file_size);
3510                         SIVAL(pdata,48,mode);
3511                         SIVAL(pdata,52,0); /* ??? */
3512                         data_size = 56;
3513                         break;
3514
3515                 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
3516                         DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
3517                         SIVAL(pdata,0,mode);
3518                         SIVAL(pdata,4,0);
3519                         data_size = 8;
3520                         break;
3521
3522                 /*
3523                  * CIFS UNIX Extensions.
3524                  */
3525
3526                 case SMB_QUERY_FILE_UNIX_BASIC:
3527
3528                         pdata = store_file_unix_basic(conn, pdata, fsp, &sbuf);
3529                         data_size = PTR_DIFF(pdata,(*ppdata));
3530
3531                         {
3532                                 int i;
3533                                 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
3534
3535                                 for (i=0; i<100; i++)
3536                                         DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
3537                                 DEBUG(4,("\n"));
3538                         }
3539
3540                         break;
3541
3542                 case SMB_QUERY_FILE_UNIX_LINK:
3543                         {
3544                                 pstring buffer;
3545
3546                                 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
3547 #ifdef S_ISLNK
3548                                 if(!S_ISLNK(sbuf.st_mode))
3549                                         return(UNIXERROR(ERRSRV,ERRbadlink));
3550 #else
3551                                 return(UNIXERROR(ERRDOS,ERRbadlink));
3552 #endif
3553                                 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1);     /* read link */
3554                                 if (len == -1)
3555                                         return(UNIXERROR(ERRDOS,ERRnoaccess));
3556                                 buffer[len] = 0;
3557                                 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
3558                                 pdata += len;
3559                                 data_size = PTR_DIFF(pdata,(*ppdata));
3560
3561                                 break;
3562                         }
3563
3564 #if defined(HAVE_POSIX_ACLS)
3565                 case SMB_QUERY_POSIX_ACL:
3566                         {
3567                                 SMB_ACL_T file_acl = NULL;
3568                                 SMB_ACL_T def_acl = NULL;
3569                                 uint16 num_file_acls = 0;
3570                                 uint16 num_def_acls = 0;
3571
3572                                 if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) {
3573                                         file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd);
3574                                 } else {
3575                                         file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
3576                                 }
3577
3578                                 if (file_acl == NULL && no_acl_syscall_error(errno)) {
3579                                         DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
3580                                                 fname ));
3581                                         return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
3582                                 }
3583
3584                                 if (S_ISDIR(sbuf.st_mode)) {
3585                                         if (fsp && fsp->is_directory) {
3586                                                 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
3587                                         } else {
3588                                                 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
3589                                         }
3590                                         def_acl = free_empty_sys_acl(conn, def_acl);
3591                                 }
3592
3593                                 num_file_acls = count_acl_entries(conn, file_acl);
3594                                 num_def_acls = count_acl_entries(conn, def_acl);
3595
3596                                 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
3597                                         DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
3598                                                 data_size,
3599                                                 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
3600                                                         SMB_POSIX_ACL_HEADER_SIZE) ));
3601                                         if (file_acl) {
3602                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3603                                         }
3604                                         if (def_acl) {
3605                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3606                                         }
3607                                         return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
3608                                 }
3609
3610                                 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
3611                                 SSVAL(pdata,2,num_file_acls);
3612                                 SSVAL(pdata,4,num_def_acls);
3613                                 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
3614                                         if (file_acl) {
3615                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3616                                         }
3617                                         if (def_acl) {
3618                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3619                                         }
3620                                         return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3621                                 }
3622                                 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
3623                                         if (file_acl) {
3624                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3625                                         }
3626                                         if (def_acl) {
3627                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3628                                         }
3629                                         return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3630                                 }
3631
3632                                 if (file_acl) {
3633                                         SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3634                                 }
3635                                 if (def_acl) {
3636                                         SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3637                                 }
3638                                 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
3639                                 break;
3640                         }
3641 #endif
3642
3643
3644                 case SMB_QUERY_POSIX_LOCK:
3645                 {
3646                         NTSTATUS status = NT_STATUS_INVALID_LEVEL;
3647                         SMB_BIG_UINT count;
3648                         SMB_BIG_UINT offset;
3649                         uint32 lock_pid;
3650                         enum brl_type lock_type;
3651
3652                         if (total_data != POSIX_LOCK_DATA_SIZE) {
3653                                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3654                         }
3655
3656                         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
3657                                 case POSIX_LOCK_TYPE_READ:
3658                                         lock_type = READ_LOCK;
3659                                         break;
3660                                 case POSIX_LOCK_TYPE_WRITE:
3661                                         lock_type = WRITE_LOCK;
3662                                         break;
3663                                 case POSIX_LOCK_TYPE_UNLOCK:
3664                                 default:
3665                                         /* There's no point in asking for an unlock... */
3666                                         talloc_destroy(data_ctx);
3667                                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3668                         }
3669
3670                         lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
3671 #if defined(HAVE_LONGLONG)
3672                         offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
3673                                         ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET));
3674                         count = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
3675                                         ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
3676 #else /* HAVE_LONGLONG */
3677                         offset = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_START_OFFSET);
3678                         count = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
3679 #endif /* HAVE_LONGLONG */
3680
3681                         status = query_lock(fsp,
3682                                         &lock_pid,
3683                                         &count,
3684                                         &offset,
3685                                         &lock_type,
3686                                         POSIX_LOCK);
3687
3688                         if (ERROR_WAS_LOCK_DENIED(status)) {
3689                                 /* Here we need to report who has it locked... */
3690                                 data_size = POSIX_LOCK_DATA_SIZE;
3691
3692                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
3693                                 SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
3694                                 SIVAL(pdata, POSIX_LOCK_PID_OFFSET, lock_pid);
3695 #if defined(HAVE_LONGLONG)
3696                                 SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF));
3697                                 SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF));
3698                                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF));
3699                                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF));
3700 #else /* HAVE_LONGLONG */
3701                                 SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
3702                                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
3703 #endif /* HAVE_LONGLONG */
3704
3705                         } else if (NT_STATUS_IS_OK(status)) {
3706                                 /* For success we just return a copy of what we sent
3707                                    with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
3708                                 data_size = POSIX_LOCK_DATA_SIZE;
3709                                 memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
3710                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
3711                         } else {
3712                                 return ERROR_NT(status);
3713                         }
3714                         break;
3715                 }
3716
3717                 default:
3718                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
3719         }
3720
3721         send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size, max_data_bytes);
3722
3723         return(-1);
3724 }
3725
3726 /****************************************************************************
3727  Set a hard link (called by UNIX extensions and by NT rename with HARD link
3728  code.
3729 ****************************************************************************/
3730
3731 NTSTATUS hardlink_internals(connection_struct *conn, pstring oldname, pstring newname)
3732 {
3733         SMB_STRUCT_STAT sbuf1, sbuf2;
3734         pstring last_component_oldname;
3735         pstring last_component_newname;
3736         NTSTATUS status = NT_STATUS_OK;
3737
3738         ZERO_STRUCT(sbuf1);
3739         ZERO_STRUCT(sbuf2);
3740
3741         status = unix_convert(conn, oldname, False, last_component_oldname, &sbuf1);
3742         if (!NT_STATUS_IS_OK(status)) {
3743                 return status;
3744         }
3745
3746         /* source must already exist. */
3747         if (!VALID_STAT(sbuf1)) {
3748                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3749         }
3750
3751         status = check_name(conn, oldname);
3752         if (!NT_STATUS_IS_OK(status)) {
3753                 return NT_STATUS_ACCESS_DENIED;
3754         }
3755
3756         status = unix_convert(conn, newname, False, last_component_newname, &sbuf2);
3757         if (!NT_STATUS_IS_OK(status)) {
3758                 return status;
3759         }
3760
3761         /* Disallow if newname already exists. */
3762         if (VALID_STAT(sbuf2)) {
3763                 return NT_STATUS_OBJECT_NAME_COLLISION;
3764         }
3765
3766         status = check_name(conn, newname);
3767         if (!NT_STATUS_IS_OK(status)) {
3768                 return NT_STATUS_ACCESS_DENIED;
3769         }
3770
3771         /* No links from a directory. */
3772         if (S_ISDIR(sbuf1.st_mode)) {
3773                 return NT_STATUS_FILE_IS_A_DIRECTORY;
3774         }
3775
3776         /* Ensure this is within the share. */
3777         status = reduce_name(conn, oldname);
3778         if (!NT_STATUS_IS_OK(status)) {
3779                 return status;
3780         }
3781
3782         DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
3783
3784         if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
3785                 status = map_nt_error_from_unix(errno);
3786                 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3787                                 nt_errstr(status), newname, oldname));
3788         }
3789
3790         return status;
3791 }
3792
3793 /****************************************************************************
3794  Deal with setting the time from any of the setfilepathinfo functions.
3795 ****************************************************************************/
3796
3797 static NTSTATUS smb_set_file_time(connection_struct *conn,
3798                                 files_struct *fsp,
3799                                 const char *fname,
3800                                 const SMB_STRUCT_STAT *psbuf,
3801                                 struct utimbuf tvs)
3802 {
3803         uint32 action =
3804                 FILE_NOTIFY_CHANGE_LAST_ACCESS
3805                 |FILE_NOTIFY_CHANGE_LAST_WRITE;
3806
3807         
3808         if (!VALID_STAT(*psbuf)) {
3809                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3810         }
3811
3812         /* get some defaults (no modifications) if any info is zero or -1. */
3813         if (null_mtime(tvs.actime)) {
3814                 tvs.actime = psbuf->st_atime;
3815                 action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
3816         }
3817
3818         if (null_mtime(tvs.modtime)) {
3819                 tvs.modtime = psbuf->st_mtime;
3820                 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
3821         }
3822
3823         DEBUG(6,("smb_set_file_time: actime: %s " , ctime(&tvs.actime)));
3824         DEBUG(6,("smb_set_file_time: modtime: %s ", ctime(&tvs.modtime)));
3825
3826         /*
3827          * Try and set the times of this file if
3828          * they are different from the current values.
3829          */
3830
3831         if (psbuf->st_mtime == tvs.modtime && psbuf->st_atime == tvs.actime) {
3832                 return NT_STATUS_OK;
3833         }
3834
3835         if(fsp != NULL) {
3836                 /*
3837                  * This was a setfileinfo on an open file.
3838                  * NT does this a lot. We also need to 
3839                  * set the time here, as it can be read by 
3840                  * FindFirst/FindNext and with the patch for bug #2045
3841                  * in smbd/fileio.c it ensures that this timestamp is
3842                  * kept sticky even after a write. We save the request
3843                  * away and will set it on file close and after a write. JRA.
3844                  */
3845
3846                 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
3847                         DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
3848                         fsp_set_pending_modtime(fsp, tvs.modtime);
3849                 }
3850
3851         }
3852         DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
3853
3854         if(file_utime(conn, fname, &tvs)!=0) {
3855                 return map_nt_error_from_unix(errno);
3856         }
3857         if (action != 0) {
3858                 notify_fname(conn, NOTIFY_ACTION_MODIFIED, action, fname);
3859         }
3860         return NT_STATUS_OK;
3861 }
3862
3863 /****************************************************************************
3864  Deal with setting the dosmode from any of the setfilepathinfo functions.
3865 ****************************************************************************/
3866
3867 static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
3868                                 const char *fname,
3869                                 SMB_STRUCT_STAT *psbuf,
3870                                 uint32 dosmode)
3871 {
3872         if (!VALID_STAT(*psbuf)) {
3873                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3874         }
3875
3876         if (dosmode) {
3877                 if (S_ISDIR(psbuf->st_mode)) {
3878                         dosmode |= aDIR;
3879                 } else {
3880                         dosmode &= ~aDIR;
3881                 }
3882         }
3883
3884         DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode));
3885
3886         /* check the mode isn't different, before changing it */
3887         if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, psbuf))) {
3888
3889                 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode 0x%x\n",
3890                                         fname, (unsigned int)dosmode ));
3891
3892                 if(file_set_dosmode(conn, fname, dosmode, psbuf, False)) {
3893                         DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of %s failed (%s)\n",
3894                                                 fname, strerror(errno)));
3895                         return map_nt_error_from_unix(errno);
3896                 }
3897         }
3898         return NT_STATUS_OK;
3899 }
3900
3901 /****************************************************************************
3902  Deal with setting the size from any of the setfilepathinfo functions.
3903 ****************************************************************************/
3904
3905 static NTSTATUS smb_set_file_size(connection_struct *conn,
3906                                 files_struct *fsp,
3907                                 const char *fname,
3908                                 SMB_STRUCT_STAT *psbuf,
3909                                 SMB_OFF_T size)
3910 {
3911         NTSTATUS status = NT_STATUS_OK;
3912         files_struct *new_fsp = NULL;
3913
3914         if (!VALID_STAT(*psbuf)) {
3915                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3916         }
3917
3918         DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size));
3919
3920         if (size == get_file_size(*psbuf)) {
3921                 return NT_STATUS_OK;
3922         }
3923
3924         DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
3925                 fname, (double)size ));
3926
3927         if (fsp && fsp->fh->fd != -1) {
3928                 /* Handle based call. */
3929                 if (vfs_set_filelen(fsp, size) == -1) {
3930                         return map_nt_error_from_unix(errno);
3931                 }
3932                 return NT_STATUS_OK;
3933         }
3934
3935         status = open_file_ntcreate(conn, fname, psbuf,
3936                                 FILE_WRITE_DATA,
3937                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3938                                 FILE_OPEN,
3939                                 0,
3940                                 FILE_ATTRIBUTE_NORMAL,
3941                                 FORCE_OPLOCK_BREAK_TO_NONE,
3942                                 NULL, &new_fsp);
3943         
3944         if (!NT_STATUS_IS_OK(status)) {
3945                 /* NB. We check for open_was_deferred in the caller. */
3946                 return status;
3947         }
3948
3949         if (vfs_set_filelen(new_fsp, size) == -1) {
3950                 status = map_nt_error_from_unix(errno);
3951                 close_file(new_fsp,NORMAL_CLOSE);
3952                 return status;
3953         }
3954
3955         close_file(new_fsp,NORMAL_CLOSE);
3956         return NT_STATUS_OK;
3957 }
3958
3959 /****************************************************************************
3960  Deal with SMB_INFO_SET_EA.
3961 ****************************************************************************/
3962
3963 static NTSTATUS smb_info_set_ea(connection_struct *conn,
3964                                 const char *pdata,
3965                                 int total_data,
3966                                 files_struct *fsp,
3967                                 const char *fname)
3968 {
3969         struct ea_list *ea_list = NULL;
3970         TALLOC_CTX *ctx = NULL;
3971         NTSTATUS status = NT_STATUS_OK;
3972
3973         if (total_data < 10) {
3974
3975                 /* OS/2 workplace shell seems to send SET_EA requests of "null"
3976                    length. They seem to have no effect. Bug #3212. JRA */
3977
3978                 if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
3979                         /* We're done. We only get EA info in this call. */
3980                         return NT_STATUS_OK;
3981                 }
3982
3983                 return NT_STATUS_INVALID_PARAMETER;
3984         }
3985
3986         if (IVAL(pdata,0) > total_data) {
3987                 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
3988                         IVAL(pdata,0), (unsigned int)total_data));
3989                 return NT_STATUS_INVALID_PARAMETER;
3990         }
3991
3992         ctx = talloc_init("SMB_INFO_SET_EA");
3993         if (!ctx) {
3994                 return NT_STATUS_NO_MEMORY;
3995         }
3996         ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
3997         if (!ea_list) {
3998                 talloc_destroy(ctx);
3999                 return NT_STATUS_INVALID_PARAMETER;
4000         }
4001         status = set_ea(conn, fsp, fname, ea_list);
4002         talloc_destroy(ctx);
4003
4004         return status;
4005 }
4006
4007 /****************************************************************************
4008  Deal with SMB_SET_FILE_DISPOSITION_INFO.
4009 ****************************************************************************/
4010
4011 static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
4012                                 const char *pdata,
4013                                 int total_data,
4014                                 files_struct *fsp,
4015                                 const char *fname,
4016                                 SMB_STRUCT_STAT *psbuf)
4017 {
4018         NTSTATUS status = NT_STATUS_OK;
4019         BOOL delete_on_close;
4020         uint32 dosmode = 0;
4021
4022         if (total_data < 1) {
4023                 return NT_STATUS_INVALID_PARAMETER;
4024         }
4025
4026         if (fsp == NULL) {
4027                 return NT_STATUS_INVALID_HANDLE;
4028         }
4029
4030         delete_on_close = (CVAL(pdata,0) ? True : False);
4031         dosmode = dos_mode(conn, fname, psbuf);
4032
4033         DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
4034                 "delete_on_close = %u\n",
4035                 fsp->fsp_name,
4036                 (unsigned int)dosmode,
4037                 (unsigned int)delete_on_close ));
4038
4039         status = can_set_delete_on_close(fsp, delete_on_close, dosmode);
4040  
4041         if (!NT_STATUS_IS_OK(status)) {
4042                 return status;
4043         }
4044
4045         /* The set is across all open files on this dev/inode pair. */
4046         if (!set_delete_on_close(fsp, delete_on_close, &current_user.ut)) {
4047                 return NT_STATUS_ACCESS_DENIED;
4048         }
4049         return NT_STATUS_OK;
4050 }
4051
4052 /****************************************************************************
4053  Deal with SMB_FILE_POSITION_INFORMATION.
4054 ****************************************************************************/
4055
4056 static NTSTATUS smb_file_position_information(connection_struct *conn,
4057                                 const char *pdata,
4058                                 int total_data,
4059                                 files_struct *fsp)
4060 {
4061         SMB_BIG_UINT position_information;
4062
4063         if (total_data < 8) {
4064                 return NT_STATUS_INVALID_PARAMETER;
4065         }
4066
4067         if (fsp == NULL) {
4068                 /* Ignore on pathname based set. */
4069                 return NT_STATUS_OK;
4070         }
4071
4072         position_information = (SMB_BIG_UINT)IVAL(pdata,0);
4073 #ifdef LARGE_SMB_OFF_T
4074         position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
4075 #else /* LARGE_SMB_OFF_T */
4076         if (IVAL(pdata,4) != 0) {
4077                 /* more than 32 bits? */
4078                 return NT_STATUS_INVALID_PARAMETER;
4079         }
4080 #endif /* LARGE_SMB_OFF_T */
4081
4082         DEBUG(10,("smb_file_position_information: Set file position information for file %s to %.0f\n",
4083                 fsp->fsp_name, (double)position_information ));
4084         fsp->fh->position_information = position_information;
4085         return NT_STATUS_OK;
4086 }
4087
4088 /****************************************************************************
4089  Deal with SMB_FILE_MODE_INFORMATION.
4090 ****************************************************************************/
4091
4092 static NTSTATUS smb_file_mode_information(connection_struct *conn,
4093                                 const char *pdata,
4094                                 int total_data)
4095 {
4096         uint32 mode;
4097
4098         if (total_data < 4) {
4099                 return NT_STATUS_INVALID_PARAMETER;
4100         }
4101         mode = IVAL(pdata,0);
4102         if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
4103                 return NT_STATUS_INVALID_PARAMETER;
4104         }
4105         return NT_STATUS_OK;
4106 }
4107
4108 /****************************************************************************
4109  Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
4110 ****************************************************************************/
4111
4112 static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
4113                                 char *inbuf,
4114                                 const char *pdata,
4115                                 int total_data,
4116                                 const char *fname)
4117 {
4118         pstring link_target;
4119         const char *newname = fname;
4120         NTSTATUS status = NT_STATUS_OK;
4121
4122         /* Set a symbolic link. */
4123         /* Don't allow this if follow links is false. */
4124
4125         if (total_data == 0) {
4126                 return NT_STATUS_INVALID_PARAMETER;
4127         }
4128
4129         if (!lp_symlinks(SNUM(conn))) {
4130                 return NT_STATUS_ACCESS_DENIED;
4131         }
4132
4133         srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), total_data, STR_TERMINATE);
4134
4135         /* !widelinks forces the target path to be within the share. */
4136         /* This means we can interpret the target as a pathname. */
4137         if (!lp_widelinks(SNUM(conn))) {
4138                 pstring rel_name;
4139                 char *last_dirp = NULL;
4140
4141                 unix_format(link_target);
4142                 if (*link_target == '/') {
4143                         /* No absolute paths allowed. */
4144                         return NT_STATUS_ACCESS_DENIED;
4145                 }
4146                 pstrcpy(rel_name, newname);
4147                 last_dirp = strrchr_m(rel_name, '/');
4148                 if (last_dirp) {
4149                         last_dirp[1] = '\0';
4150                 } else {
4151                         pstrcpy(rel_name, "./");
4152                 }
4153                 pstrcat(rel_name, link_target);
4154
4155                 status = check_name(conn, rel_name);
4156                 if (!NT_STATUS_IS_OK(status)) {
4157                         return status;
4158                 }
4159         }
4160
4161         DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
4162                         newname, link_target ));
4163
4164         if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0) {
4165                 return map_nt_error_from_unix(errno);
4166         }
4167
4168         return NT_STATUS_OK;
4169 }
4170
4171 /****************************************************************************
4172  Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
4173 ****************************************************************************/
4174
4175 static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
4176                                 char *inbuf,
4177                                 char *outbuf,
4178                                 const char *pdata,
4179                                 int total_data,
4180                                 pstring fname)
4181 {
4182         pstring oldname;
4183         NTSTATUS status = NT_STATUS_OK;
4184
4185         /* Set a hard link. */
4186         if (total_data == 0) {
4187                 return NT_STATUS_INVALID_PARAMETER;
4188         }
4189
4190         srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), total_data, STR_TERMINATE, &status);
4191         if (!NT_STATUS_IS_OK(status)) {
4192                 return status;
4193         }
4194
4195         RESOLVE_DFSPATH_STATUS(oldname, conn, inbuf, outbuf);
4196
4197         DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
4198                 fname, oldname));
4199
4200         return hardlink_internals(conn, oldname, fname);
4201 }
4202
4203 /****************************************************************************
4204  Deal with SMB_FILE_RENAME_INFORMATION.
4205 ****************************************************************************/
4206
4207 static NTSTATUS smb_file_rename_information(connection_struct *conn,
4208                                 char *inbuf,
4209                                 char *outbuf,
4210                                 const char *pdata,
4211                                 int total_data,
4212                                 files_struct *fsp,
4213                                 pstring fname)
4214 {
4215         BOOL overwrite;
4216         /* uint32 root_fid; */  /* Not used */
4217         uint32 len;
4218         pstring newname;
4219         pstring base_name;
4220         NTSTATUS status = NT_STATUS_OK;
4221         char *p;
4222
4223         if (total_data < 13) {
4224                 return NT_STATUS_INVALID_PARAMETER;
4225         }
4226
4227         overwrite = (CVAL(pdata,0) ? True : False);
4228         /* root_fid = IVAL(pdata,4); */
4229         len = IVAL(pdata,8);
4230
4231         if (len > (total_data - 12) || (len == 0)) {
4232                 return NT_STATUS_INVALID_PARAMETER;
4233         }
4234
4235         srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status);
4236         if (!NT_STATUS_IS_OK(status)) {
4237                 return status;
4238         }
4239
4240         RESOLVE_DFSPATH_STATUS(newname, conn, inbuf, outbuf);
4241
4242         /* Check the new name has no '/' characters. */
4243         if (strchr_m(newname, '/')) {
4244                 return NT_STATUS_NOT_SUPPORTED;
4245         }
4246
4247         /* Create the base directory. */
4248         pstrcpy(base_name, fname);
4249         p = strrchr_m(base_name, '/');
4250         if (p) {
4251                 *p = '\0';
4252         }
4253         /* Append the new name. */
4254         pstrcat(base_name, "/");
4255         pstrcat(base_name, newname);
4256
4257         if (fsp) {
4258                 DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
4259                         fsp->fnum, fsp->fsp_name, base_name ));
4260                 status = rename_internals_fsp(conn, fsp, base_name, 0, overwrite);
4261         } else {
4262                 DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
4263                         fname, newname ));
4264                 status = rename_internals(conn, fname, base_name, 0, overwrite, False);
4265         }
4266
4267         return status;
4268 }
4269
4270 /****************************************************************************
4271  Deal with SMB_SET_POSIX_ACL.
4272 ****************************************************************************/
4273
4274 #if defined(HAVE_POSIX_ACLS)
4275 static NTSTATUS smb_set_posix_acl(connection_struct *conn,
4276                                 const char *pdata,
4277                                 int total_data,
4278                                 files_struct *fsp,
4279                                 const char *fname,
4280                                 SMB_STRUCT_STAT *psbuf)
4281 {
4282         uint16 posix_acl_version;
4283         uint16 num_file_acls;
4284         uint16 num_def_acls;
4285         BOOL valid_file_acls = True;
4286         BOOL valid_def_acls = True;
4287
4288         if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
4289                 return NT_STATUS_INVALID_PARAMETER;
4290         }
4291         posix_acl_version = SVAL(pdata,0);
4292         num_file_acls = SVAL(pdata,2);
4293         num_def_acls = SVAL(pdata,4);
4294
4295         if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4296                 valid_file_acls = False;
4297                 num_file_acls = 0;
4298         }
4299
4300         if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4301                 valid_def_acls = False;
4302                 num_def_acls = 0;
4303         }
4304
4305         if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
4306                 return NT_STATUS_INVALID_PARAMETER;
4307         }
4308
4309         if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
4310                         (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
4311                 return NT_STATUS_INVALID_PARAMETER;
4312         }
4313
4314         DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
4315                 fname ? fname : fsp->fsp_name,
4316                 (unsigned int)num_file_acls,
4317                 (unsigned int)num_def_acls));
4318
4319         if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
4320                         pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
4321                 return map_nt_error_from_unix(errno);
4322         }
4323
4324         if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, psbuf, num_def_acls,
4325                         pdata + SMB_POSIX_ACL_HEADER_SIZE +
4326                         (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
4327                 return map_nt_error_from_unix(errno);
4328         }
4329         return NT_STATUS_OK;
4330 }
4331 #endif
4332
4333 /****************************************************************************
4334  Deal with SMB_SET_POSIX_LOCK.
4335 ****************************************************************************/
4336
4337 static NTSTATUS smb_set_posix_lock(connection_struct *conn,
4338                                 char *inbuf,
4339                                 int length,
4340                                 const char *pdata,
4341                                 int total_data,
4342                                 files_struct *fsp)
4343 {
4344         SMB_BIG_UINT count;
4345         SMB_BIG_UINT offset;
4346         uint32 lock_pid;
4347         BOOL blocking_lock = False;
4348         enum brl_type lock_type;
4349         NTSTATUS status = NT_STATUS_OK;
4350
4351         if (fsp == NULL || fsp->fh->fd == -1) {
4352                 return NT_STATUS_INVALID_HANDLE;
4353         }
4354
4355         if (total_data != POSIX_LOCK_DATA_SIZE) {
4356                 return NT_STATUS_INVALID_PARAMETER;
4357         }
4358
4359         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
4360                 case POSIX_LOCK_TYPE_READ:
4361                         lock_type = READ_LOCK;
4362                         break;
4363                 case POSIX_LOCK_TYPE_WRITE:
4364                         /* Return the right POSIX-mappable error code for files opened read-only. */
4365                         if (!fsp->can_write) {
4366                                 return NT_STATUS_INVALID_HANDLE;
4367                         }
4368                         lock_type = WRITE_LOCK;
4369                         break;
4370                 case POSIX_LOCK_TYPE_UNLOCK:
4371                         lock_type = UNLOCK_LOCK;
4372                         break;
4373                 default:
4374                         return NT_STATUS_INVALID_PARAMETER;
4375         }
4376
4377         if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_NOWAIT) {
4378                 blocking_lock = False;
4379         } else if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_WAIT) {
4380                 blocking_lock = True;
4381         } else {
4382                 return NT_STATUS_INVALID_PARAMETER;
4383         }
4384
4385         if (!lp_blocking_locks(SNUM(conn))) { 
4386                 blocking_lock = False;
4387         }
4388
4389         lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
4390 #if defined(HAVE_LONGLONG)
4391         offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
4392                         ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET));
4393         count = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
4394                         ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
4395 #else /* HAVE_LONGLONG */
4396         offset = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_START_OFFSET);
4397         count = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
4398 #endif /* HAVE_LONGLONG */
4399
4400         DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
4401                         "lock_pid = %u, count = %.0f, offset = %.0f\n",
4402                 fsp->fsp_name,
4403                 (unsigned int)lock_type,
4404                 (unsigned int)lock_pid,
4405                 (double)count,
4406                 (double)offset ));
4407
4408         if (lock_type == UNLOCK_LOCK) {
4409                 status = do_unlock(fsp,
4410                                 lock_pid,
4411                                 count,
4412                                 offset,
4413                                 POSIX_LOCK);
4414         } else {
4415                 struct byte_range_lock *br_lck = do_lock(fsp,
4416                                                         lock_pid,
4417                                                         count,
4418                                                         offset,
4419                                                         lock_type,
4420                                                         POSIX_LOCK,
4421                                                         blocking_lock,
4422                                                         &status);
4423
4424                 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
4425                         /*
4426                          * A blocking lock was requested. Package up
4427                          * this smb into a queued request and push it
4428                          * onto the blocking lock queue.
4429                          */
4430                         if(push_blocking_lock_request(br_lck,
4431                                                 inbuf, length,
4432                                                 fsp,
4433                                                 -1, /* infinite timeout. */
4434                                                 0,
4435                                                 lock_pid,
4436                                                 lock_type,
4437                                                 POSIX_LOCK,
4438                                                 offset,
4439                                                 count)) {
4440                                 TALLOC_FREE(br_lck);
4441                                 return status;
4442                         }
4443                 }
4444                 TALLOC_FREE(br_lck);
4445         }
4446
4447         return status;
4448 }
4449
4450 /****************************************************************************
4451  Deal with SMB_INFO_STANDARD.
4452 ****************************************************************************/
4453
4454 static NTSTATUS smb_set_info_standard(connection_struct *conn,
4455                                         const char *pdata,
4456                                         int total_data,
4457                                         files_struct *fsp,
4458                                         const char *fname,
4459                                         const SMB_STRUCT_STAT *psbuf)
4460 {
4461         struct utimbuf tvs;
4462
4463         if (total_data < 12) {
4464                 return NT_STATUS_INVALID_PARAMETER;
4465         }
4466
4467         /* access time */
4468         tvs.actime = srv_make_unix_date2(pdata+l1_fdateLastAccess);
4469         /* write time */
4470         tvs.modtime = srv_make_unix_date2(pdata+l1_fdateLastWrite);
4471
4472         DEBUG(10,("smb_set_info_standard: file %s\n",
4473                 fname ? fname : fsp->fsp_name ));
4474
4475         return smb_set_file_time(conn,
4476                                 fsp,
4477                                 fname,
4478                                 psbuf,
4479                                 tvs);
4480 }
4481
4482 /****************************************************************************
4483  Deal with SMB_SET_FILE_BASIC_INFO.
4484 ****************************************************************************/
4485
4486 static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
4487                                         const char *pdata,
4488                                         int total_data,
4489                                         files_struct *fsp,
4490                                         const char *fname,
4491                                         SMB_STRUCT_STAT *psbuf)
4492 {
4493         /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
4494         time_t write_time;
4495         time_t changed_time;
4496         uint32 dosmode = 0;
4497         struct utimbuf tvs;
4498         NTSTATUS status = NT_STATUS_OK;
4499
4500         if (total_data < 36) {
4501                 return NT_STATUS_INVALID_PARAMETER;
4502         }
4503
4504         /* Set the attributes */
4505         dosmode = IVAL(pdata,32);
4506         status = smb_set_file_dosmode(conn,
4507                                         fname,
4508                                         psbuf,
4509                                         dosmode);
4510         if (!NT_STATUS_IS_OK(status)) {
4511                 return status;
4512         }
4513
4514         /* Ignore create time at offset pdata. */
4515
4516         /* access time */
4517         tvs.actime = convert_timespec_to_time_t(interpret_long_date(pdata+8));
4518
4519         write_time = convert_timespec_to_time_t(interpret_long_date(pdata+16));
4520         changed_time = convert_timespec_to_time_t(interpret_long_date(pdata+24));
4521
4522         tvs.modtime = MIN(write_time, changed_time);
4523
4524         if (write_time > tvs.modtime && write_time != (time_t)-1) {
4525                 tvs.modtime = write_time;
4526         }
4527         /* Prefer a defined time to an undefined one. */
4528         if (null_mtime(tvs.modtime)) {
4529                 tvs.modtime = null_mtime(write_time) ? changed_time : write_time;
4530         }
4531
4532         DEBUG(10,("smb_set_file_basic_info: file %s\n",
4533                 fname ? fname : fsp->fsp_name ));
4534
4535         return smb_set_file_time(conn,
4536                                 fsp,
4537                                 fname,
4538                                 psbuf,
4539                                 tvs);
4540 }
4541
4542 /****************************************************************************
4543  Deal with SMB_SET_FILE_ALLOCATION_INFO.
4544 ****************************************************************************/
4545
4546 static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
4547                                         const char *pdata,
4548                                         int total_data,
4549                                         files_struct *fsp,
4550                                         const char *fname,
4551                                         SMB_STRUCT_STAT *psbuf)
4552 {
4553         SMB_BIG_UINT allocation_size = 0;
4554         NTSTATUS status = NT_STATUS_OK;
4555         files_struct *new_fsp = NULL;
4556
4557         if (!VALID_STAT(*psbuf)) {
4558                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4559         }
4560
4561         if (total_data < 8) {
4562                 return NT_STATUS_INVALID_PARAMETER;
4563         }
4564
4565         allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
4566 #ifdef LARGE_SMB_OFF_T
4567         allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
4568 #else /* LARGE_SMB_OFF_T */
4569         if (IVAL(pdata,4) != 0) {
4570                 /* more than 32 bits? */
4571                 return NT_STATUS_INVALID_PARAMETER;
4572         }
4573 #endif /* LARGE_SMB_OFF_T */
4574
4575         DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for file %s to %.0f\n",
4576                         fname, (double)allocation_size ));
4577
4578         if (allocation_size) {
4579                 allocation_size = smb_roundup(conn, allocation_size);
4580         }
4581
4582         if(allocation_size == get_file_size(*psbuf)) {
4583                 return NT_STATUS_OK;
4584         }
4585  
4586         DEBUG(10,("smb_set_file_allocation_info: file %s : setting new allocation size to %.0f\n",
4587                         fname, (double)allocation_size ));
4588  
4589         if (fsp && fsp->fh->fd != -1) {
4590                 /* Open file handle. */
4591                 if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
4592                         return map_nt_error_from_unix(errno);
4593                 }
4594                 return NT_STATUS_OK;
4595         }
4596
4597         /* Pathname or stat or directory file. */
4598
4599         status = open_file_ntcreate(conn, fname, psbuf,
4600                                 FILE_WRITE_DATA,
4601                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4602                                 FILE_OPEN,
4603                                 0,
4604                                 FILE_ATTRIBUTE_NORMAL,
4605                                 FORCE_OPLOCK_BREAK_TO_NONE,
4606                                 NULL, &new_fsp);
4607  
4608         if (!NT_STATUS_IS_OK(status)) {
4609                 /* NB. We check for open_was_deferred in the caller. */
4610                 return status;
4611         }
4612         if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
4613                 status = map_nt_error_from_unix(errno);
4614                 close_file(new_fsp,NORMAL_CLOSE);
4615                 return status;
4616         }
4617
4618         close_file(new_fsp,NORMAL_CLOSE);
4619         return NT_STATUS_OK;
4620 }
4621
4622 /****************************************************************************
4623  Deal with SMB_SET_FILE_END_OF_FILE_INFO.
4624 ****************************************************************************/
4625
4626 static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
4627                                         const char *pdata,
4628                                         int total_data,
4629                                         files_struct *fsp,
4630                                         const char *fname,
4631                                         SMB_STRUCT_STAT *psbuf)
4632 {
4633         SMB_OFF_T size;
4634
4635         if (total_data < 8) {
4636                 return NT_STATUS_INVALID_PARAMETER;
4637         }
4638
4639         size = IVAL(pdata,0);
4640 #ifdef LARGE_SMB_OFF_T
4641         size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
4642 #else /* LARGE_SMB_OFF_T */
4643         if (IVAL(pdata,4) != 0) {
4644                 /* more than 32 bits? */
4645                 return NT_STATUS_INVALID_PARAMETER;
4646         }
4647 #endif /* LARGE_SMB_OFF_T */
4648         DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
4649                 "file %s to %.0f\n", fname, (double)size ));
4650
4651         return smb_set_file_size(conn,
4652                                 fsp,
4653                                 fname,
4654                                 psbuf,
4655                                 size);
4656 }
4657
4658 /****************************************************************************
4659  Allow a UNIX info mknod.
4660 ****************************************************************************/
4661
4662 static NTSTATUS smb_unix_mknod(connection_struct *conn,
4663                                         const char *pdata,
4664                                         int total_data,
4665                                         const char *fname,
4666                                         SMB_STRUCT_STAT *psbuf)
4667 {
4668         uint32 file_type = IVAL(pdata,56);
4669 #if defined(HAVE_MAKEDEV)
4670         uint32 dev_major = IVAL(pdata,60);
4671         uint32 dev_minor = IVAL(pdata,68);
4672 #endif
4673         SMB_DEV_T dev = (SMB_DEV_T)0;
4674         uint32 raw_unixmode = IVAL(pdata,84);
4675         NTSTATUS status;
4676         mode_t unixmode;
4677
4678         if (total_data < 100) {
4679                 return NT_STATUS_INVALID_PARAMETER;
4680         }
4681
4682         status = unix_perms_from_wire(conn, psbuf, raw_unixmode, PERM_NEW_FILE, &unixmode);
4683         if (!NT_STATUS_IS_OK(status)) {
4684                 return status;
4685         }
4686
4687 #if defined(HAVE_MAKEDEV)
4688         dev = makedev(dev_major, dev_minor);
4689 #endif
4690
4691         switch (file_type) {
4692 #if defined(S_IFIFO)
4693                 case UNIX_TYPE_FIFO:
4694                         unixmode |= S_IFIFO;
4695                         break;
4696 #endif
4697 #if defined(S_IFSOCK)
4698                 case UNIX_TYPE_SOCKET:
4699                         unixmode |= S_IFSOCK;
4700                         break;
4701 #endif
4702 #if defined(S_IFCHR)
4703                 case UNIX_TYPE_CHARDEV:
4704                         unixmode |= S_IFCHR;
4705                         break;
4706 #endif
4707 #if defined(S_IFBLK)
4708                 case UNIX_TYPE_BLKDEV:
4709                         unixmode |= S_IFBLK;
4710                         break;
4711 #endif
4712                 default:
4713                         return NT_STATUS_INVALID_PARAMETER;
4714         }
4715
4716         DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
4717 0%o for file %s\n", (double)dev, (unsigned int)unixmode, fname ));
4718
4719         /* Ok - do the mknod. */
4720         if (SMB_VFS_MKNOD(conn, fname, unixmode, dev) != 0) {
4721                 return map_nt_error_from_unix(errno);
4722         }
4723
4724         /* If any of the other "set" calls fail we
4725          * don't want to end up with a half-constructed mknod.
4726          */
4727
4728         if (lp_inherit_perms(SNUM(conn))) {
4729                 inherit_access_acl(
4730                         conn, parent_dirname(fname),
4731                         fname, unixmode);
4732         }
4733
4734         if (SMB_VFS_STAT(conn, fname, psbuf) != 0) {
4735                 status = map_nt_error_from_unix(errno);
4736                 SMB_VFS_UNLINK(conn,fname);
4737                 return status;
4738         }
4739         return NT_STATUS_OK;
4740 }
4741
4742 /****************************************************************************
4743  Deal with SMB_SET_FILE_UNIX_BASIC.
4744 ****************************************************************************/
4745
4746 static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
4747                                         const char *pdata,
4748                                         int total_data,
4749                                         files_struct *fsp,
4750                                         const char *fname,
4751                                         SMB_STRUCT_STAT *psbuf)
4752 {
4753         struct utimbuf tvs;
4754         uint32 raw_unixmode;
4755         mode_t unixmode;
4756         SMB_OFF_T size = 0;
4757         uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
4758         gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
4759         NTSTATUS status = NT_STATUS_OK;
4760         BOOL delete_on_fail = False;
4761         enum perm_type ptype;
4762
4763         if (total_data < 100) {
4764                 return NT_STATUS_INVALID_PARAMETER;
4765         }
4766
4767         if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
4768            IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
4769                 size=IVAL(pdata,0); /* first 8 Bytes are size */
4770 #ifdef LARGE_SMB_OFF_T
4771                 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
4772 #else /* LARGE_SMB_OFF_T */
4773                 if (IVAL(pdata,4) != 0) {
4774                         /* more than 32 bits? */
4775                         return NT_STATUS_INVALID_PARAMETER;
4776                 }
4777 #endif /* LARGE_SMB_OFF_T */
4778         }
4779
4780         tvs.actime = convert_timespec_to_time_t(interpret_long_date(pdata+24)); /* access_time */
4781         tvs.modtime = convert_timespec_to_time_t(interpret_long_date(pdata+32)); /* modification_time */
4782         set_owner = (uid_t)IVAL(pdata,40);
4783         set_grp = (gid_t)IVAL(pdata,48);
4784         raw_unixmode = IVAL(pdata,84);
4785
4786         if (VALID_STAT(*psbuf)) {
4787                 if (S_ISDIR(psbuf->st_mode)) {
4788                         ptype = PERM_EXISTING_DIR;
4789                 } else {
4790                         ptype = PERM_EXISTING_FILE;
4791                 }
4792         } else {
4793                 ptype = PERM_NEW_FILE;
4794         }
4795
4796         status = unix_perms_from_wire(conn, psbuf, raw_unixmode, ptype, &unixmode);
4797         if (!NT_STATUS_IS_OK(status)) {
4798                 return status;
4799         }
4800
4801         DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = %s \
4802 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
4803                 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
4804
4805         if (!VALID_STAT(*psbuf)) {
4806                 /*
4807                  * The only valid use of this is to create character and block
4808                  * devices, and named pipes. This is deprecated (IMHO) and 
4809                  * a new info level should be used for mknod. JRA.
4810                  */
4811
4812                 status = smb_unix_mknod(conn,
4813                                         pdata,
4814                                         total_data,
4815                                         fname,
4816                                         psbuf);
4817                 if (!NT_STATUS_IS_OK(status)) {
4818                         return status;
4819                 }
4820
4821                 /* Ensure we don't try and change anything else. */
4822                 raw_unixmode = SMB_MODE_NO_CHANGE;
4823                 size = get_file_size(*psbuf);
4824                 tvs.modtime = psbuf->st_mtime;
4825                 tvs.actime = psbuf->st_atime;
4826                 /* 
4827                  * We continue here as we might want to change the 
4828                  * owner uid/gid.
4829                  */
4830                 delete_on_fail = True;
4831         }
4832
4833 #if 1
4834         /* Horrible backwards compatibility hack as an old server bug
4835          * allowed a CIFS client bug to remain unnoticed :-(. JRA.
4836          * */
4837
4838         if (!size) {
4839                 size = get_file_size(*psbuf);
4840         }
4841 #endif
4842
4843         /*
4844          * Deal with the UNIX specific mode set.
4845          */
4846
4847         if (raw_unixmode != SMB_MODE_NO_CHANGE) {
4848                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
4849                         (unsigned int)unixmode, fname ));
4850                 if (SMB_VFS_CHMOD(conn, fname, unixmode) != 0) {
4851                         return map_nt_error_from_unix(errno);
4852                 }
4853         }
4854
4855         /*
4856          * Deal with the UNIX specific uid set.
4857          */
4858
4859         if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (psbuf->st_uid != set_owner)) {
4860                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
4861                         (unsigned int)set_owner, fname ));
4862                 if (SMB_VFS_CHOWN(conn, fname, set_owner, (gid_t)-1) != 0) {
4863                         status = map_nt_error_from_unix(errno);
4864                         if (delete_on_fail) {
4865                                 SMB_VFS_UNLINK(conn,fname);
4866                         }
4867                         return status;
4868                 }
4869         }
4870
4871         /*
4872          * Deal with the UNIX specific gid set.
4873          */
4874
4875         if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (psbuf->st_gid != set_grp)) {
4876                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
4877                         (unsigned int)set_owner, fname ));
4878                 if (SMB_VFS_CHOWN(conn, fname, (uid_t)-1, set_grp) != 0) {
4879                         status = map_nt_error_from_unix(errno);
4880                         if (delete_on_fail) {
4881                                 SMB_VFS_UNLINK(conn,fname);
4882                         }
4883                         return status;
4884                 }
4885         }
4886
4887         /* Deal with any size changes. */
4888
4889         status = smb_set_file_size(conn,
4890                                 fsp,
4891                                 fname,
4892                                 psbuf,
4893                                 size);
4894         if (!NT_STATUS_IS_OK(status)) {
4895                 return status;
4896         }
4897
4898         /* Deal with any time changes. */
4899
4900         return smb_set_file_time(conn,
4901                                 fsp,
4902                                 fname,
4903                                 psbuf,
4904                                 tvs);
4905 }
4906
4907 /****************************************************************************
4908  Create a directory with POSIX semantics.
4909 ****************************************************************************/
4910
4911 static NTSTATUS smb_posix_mkdir(connection_struct *conn,
4912                                 char **ppdata,
4913                                 int total_data,
4914                                 const char *fname,
4915                                 SMB_STRUCT_STAT *psbuf,
4916                                 int *pdata_return_size)
4917 {
4918         NTSTATUS status = NT_STATUS_OK;
4919         uint32 raw_unixmode = 0;
4920         uint32 mod_unixmode = 0;
4921         mode_t unixmode = (mode_t)0;
4922         files_struct *fsp = NULL;
4923         uint16 info_level_return = 0;
4924         char *pdata = *ppdata;
4925
4926         if (total_data < 10) {
4927                 return NT_STATUS_INVALID_PARAMETER;
4928         }
4929
4930         raw_unixmode = IVAL(pdata,8);
4931         status = unix_perms_from_wire(conn, psbuf, raw_unixmode, PERM_NEW_DIR, &unixmode);
4932         if (!NT_STATUS_IS_OK(status)) {
4933                 return status;
4934         }
4935
4936         mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
4937
4938         DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
4939                 fname, (unsigned int)unixmode ));
4940
4941         status = open_directory(conn,
4942                                 fname,
4943                                 psbuf,
4944                                 FILE_READ_ATTRIBUTES, /* Just a stat open */
4945                                 FILE_SHARE_NONE, /* Ignored for stat opens */
4946                                 FILE_CREATE,
4947                                 0,
4948                                 mod_unixmode,
4949                                 NULL,
4950                                 &fsp);
4951
4952         if (NT_STATUS_IS_OK(status)) {
4953                 close_file(fsp, NORMAL_CLOSE);
4954         }
4955
4956         info_level_return = SVAL(pdata,12);
4957  
4958         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
4959                 *pdata_return_size = 8 + SMB_FILE_UNIX_BASIC_SIZE;
4960         } else {
4961                 *pdata_return_size = 8;
4962         }
4963
4964         /* Realloc the data size */
4965         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
4966         if (*ppdata == NULL) {
4967                 *pdata_return_size = 0;
4968                 return NT_STATUS_NO_MEMORY;
4969         }
4970
4971         SSVAL(pdata,0,NO_OPLOCK_RETURN);
4972         SSVAL(pdata,2,0);
4973
4974         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
4975                 SSVAL(pdata,4,SMB_QUERY_FILE_UNIX_BASIC);
4976                 SSVAL(pdata,6,0); /* Padding. */
4977                 store_file_unix_basic(conn, pdata + 8, fsp, psbuf);
4978         } else {
4979                 SSVAL(pdata,4,SMB_NO_INFO_LEVEL_RETURNED);
4980                 SSVAL(pdata,6,0); /* Padding. */
4981         }
4982
4983         return status;
4984 }
4985
4986 /****************************************************************************
4987  Open/Create a file with POSIX semantics.
4988 ****************************************************************************/
4989
4990 static NTSTATUS smb_posix_open(connection_struct *conn,
4991                                 char **ppdata,
4992                                 int total_data,
4993                                 const char *fname,
4994                                 SMB_STRUCT_STAT *psbuf,
4995                                 int *pdata_return_size)
4996 {
4997         BOOL extended_oplock_granted = False;
4998         char *pdata = *ppdata;
4999         uint32 flags = 0;
5000         uint32 wire_open_mode = 0;
5001         uint32 raw_unixmode = 0;
5002         uint32 mod_unixmode = 0;
5003         uint32 create_disp = 0;
5004         uint32 access_mask = 0;
5005         uint32 create_options = 0;
5006         NTSTATUS status = NT_STATUS_OK;
5007         mode_t unixmode = (mode_t)0;
5008         files_struct *fsp = NULL;
5009         int oplock_request = 0;
5010         int info = 0;
5011         uint16 info_level_return = 0;
5012
5013         if (total_data < 14) {
5014                 return NT_STATUS_INVALID_PARAMETER;
5015         }
5016
5017         flags = IVAL(pdata,0);
5018         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
5019         if (oplock_request) {
5020                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
5021         }
5022
5023         wire_open_mode = IVAL(pdata,4);
5024
5025         if (wire_open_mode == (SMB_O_CREAT|SMB_O_DIRECTORY)) {
5026                 return smb_posix_mkdir(conn,
5027                                         ppdata,
5028                                         total_data,
5029                                         fname,
5030                                         psbuf,
5031                                         pdata_return_size);
5032         }
5033
5034         switch (wire_open_mode & SMB_ACCMODE) {
5035                 case SMB_O_RDONLY:
5036                         access_mask = FILE_READ_DATA;
5037                         break;
5038                 case SMB_O_WRONLY:
5039                         access_mask = FILE_WRITE_DATA;
5040                         break;
5041                 case SMB_O_RDWR:
5042                         access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
5043                         break;
5044                 default:
5045                         DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
5046                                 (unsigned int)wire_open_mode ));
5047                         return NT_STATUS_INVALID_PARAMETER;
5048         }
5049
5050         wire_open_mode &= ~SMB_ACCMODE;
5051
5052         if((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) == (SMB_O_CREAT | SMB_O_EXCL)) {
5053                 create_disp = FILE_CREATE;
5054         } else if((wire_open_mode & (SMB_O_CREAT | SMB_O_TRUNC)) == (SMB_O_CREAT | SMB_O_TRUNC)) {
5055                 create_disp = FILE_OVERWRITE_IF;
5056         } else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) {
5057                 create_disp = FILE_OPEN_IF;
5058         } else {
5059                 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
5060                         (unsigned int)wire_open_mode ));
5061                 return NT_STATUS_INVALID_PARAMETER;
5062         }
5063
5064         raw_unixmode = IVAL(pdata,8);
5065         status = unix_perms_from_wire(conn,
5066                                 psbuf,
5067                                 raw_unixmode,
5068                                 VALID_STAT(*psbuf) ? PERM_EXISTING_FILE : PERM_NEW_FILE,
5069                                 &unixmode);
5070
5071         if (!NT_STATUS_IS_OK(status)) {
5072                 return status;
5073         }
5074
5075         mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
5076
5077         if (wire_open_mode & SMB_O_SYNC) {
5078                 create_options |= FILE_WRITE_THROUGH;
5079         }
5080         if (wire_open_mode & SMB_O_APPEND) {
5081                 access_mask |= FILE_APPEND_DATA;
5082         }
5083         if (wire_open_mode & SMB_O_DIRECT) {
5084                 mod_unixmode |= FILE_FLAG_NO_BUFFERING;
5085         }
5086
5087         DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
5088                 fname,
5089                 (unsigned int)wire_open_mode,
5090                 (unsigned int)unixmode ));
5091
5092         status = open_file_ntcreate(conn,
5093                                 fname,
5094                                 psbuf,
5095                                 access_mask,
5096                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5097                                 create_disp,
5098                                 0,              /* no create options yet. */
5099                                 mod_unixmode,
5100                                 oplock_request,
5101                                 &info,
5102                                 &fsp);
5103
5104         if (!NT_STATUS_IS_OK(status)) {
5105                 return status;
5106         }
5107
5108         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
5109                 extended_oplock_granted = True;
5110         }
5111
5112         if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
5113                 extended_oplock_granted = True;
5114         }
5115
5116         info_level_return = SVAL(pdata,12);
5117  
5118         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
5119                 *pdata_return_size = 8 + SMB_FILE_UNIX_BASIC_SIZE;
5120         } else {
5121                 *pdata_return_size = 8;
5122         }
5123
5124         /* Realloc the data size */
5125         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
5126         if (*ppdata == NULL) {
5127                 close_file(fsp,ERROR_CLOSE);
5128                 *pdata_return_size = 0;
5129                 return NT_STATUS_NO_MEMORY;
5130         }
5131
5132         if (extended_oplock_granted) {
5133                 if (flags & REQUEST_BATCH_OPLOCK) {
5134                         SSVAL(pdata,0, BATCH_OPLOCK_RETURN);
5135                 } else {
5136                         SSVAL(pdata,0, EXCLUSIVE_OPLOCK_RETURN);
5137                 }
5138         } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
5139                 SSVAL(pdata,0, LEVEL_II_OPLOCK_RETURN);
5140         } else {
5141                 SSVAL(pdata,0,NO_OPLOCK_RETURN);
5142         }
5143
5144         SSVAL(pdata,2,fsp->fnum);
5145         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
5146                 SSVAL(pdata,4,SMB_QUERY_FILE_UNIX_BASIC);
5147                 SSVAL(pdata,6,0); /* padding. */
5148                 store_file_unix_basic(conn, pdata + 8, fsp, psbuf);
5149         } else {
5150                 SSVAL(pdata,4,SMB_NO_INFO_LEVEL_RETURNED);
5151                 SSVAL(pdata,6,0); /* padding. */
5152         }
5153         return NT_STATUS_OK;
5154 }
5155
5156 /****************************************************************************
5157  Delete a file with POSIX semantics.
5158 ****************************************************************************/
5159
5160 static NTSTATUS smb_posix_unlink(connection_struct *conn,
5161                                 const char *pdata,
5162                                 int total_data,
5163                                 const char *fname,
5164                                 SMB_STRUCT_STAT *psbuf)
5165 {
5166         NTSTATUS status = NT_STATUS_OK;
5167         files_struct *fsp = NULL;
5168         uint16 flags = 0;
5169         int info = 0;
5170
5171         if (total_data < 2) {
5172                 return NT_STATUS_INVALID_PARAMETER;
5173         }
5174
5175         flags = SVAL(pdata,0);
5176
5177         if (!VALID_STAT(*psbuf)) {
5178                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5179         }
5180
5181         if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
5182                         !VALID_STAT_OF_DIR(*psbuf)) {
5183                 return NT_STATUS_NOT_A_DIRECTORY;
5184         }
5185
5186         DEBUG(10,("smb_posix_unlink: %s %s\n",
5187                 (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
5188                 fname));
5189
5190         if (VALID_STAT_OF_DIR(*psbuf)) {
5191                 status = open_directory(conn,
5192                                         fname,
5193                                         psbuf,
5194                                         DELETE_ACCESS,
5195                                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5196                                         FILE_OPEN,
5197                                         FILE_DELETE_ON_CLOSE,
5198                                         FILE_FLAG_POSIX_SEMANTICS|0777,
5199                                         &info,                          
5200                                         &fsp);
5201         } else {
5202                 char del = 1;
5203
5204                 status = open_file_ntcreate(conn,
5205                                 fname,
5206                                 psbuf,
5207                                 DELETE_ACCESS,
5208                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5209                                 FILE_OPEN,
5210                                 0,
5211                                 FILE_FLAG_POSIX_SEMANTICS|0777,
5212                                 INTERNAL_OPEN_ONLY,
5213                                 &info,
5214                                 &fsp);
5215                 /* 
5216                  * For file opens we must set the delete on close
5217                  * after the open.
5218                  */
5219
5220                 if (!NT_STATUS_IS_OK(status)) {
5221                         return status;
5222                 }
5223
5224                 status = smb_set_file_disposition_info(conn,
5225                                                         &del,
5226                                                         1,
5227                                                         fsp,
5228                                                         fname,
5229                                                         psbuf);
5230         }
5231
5232         if (!NT_STATUS_IS_OK(status)) {
5233                 return status;
5234         }
5235         return close_file(fsp, NORMAL_CLOSE);
5236 }
5237
5238 /****************************************************************************
5239  Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
5240 ****************************************************************************/
5241
5242 static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
5243                                         unsigned int tran_call,
5244                                         char **pparams, int total_params, char **ppdata, int total_data,
5245                                         unsigned int max_data_bytes)
5246 {
5247         char *params = *pparams;
5248         char *pdata = *ppdata;
5249         uint16 info_level;
5250         SMB_STRUCT_STAT sbuf;
5251         pstring fname;
5252         files_struct *fsp = NULL;
5253         NTSTATUS status = NT_STATUS_OK;
5254         int data_return_size = 0;
5255
5256         if (!params) {
5257                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5258         }
5259
5260         ZERO_STRUCT(sbuf);
5261
5262         if (tran_call == TRANSACT2_SETFILEINFO) {
5263                 if (total_params < 4) {
5264                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5265                 }
5266
5267                 fsp = file_fsp(params,0);
5268                 info_level = SVAL(params,2);    
5269
5270                 if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
5271                         /*
5272                          * This is actually a SETFILEINFO on a directory
5273                          * handle (returned from an NT SMB). NT5.0 seems
5274                          * to do this call. JRA.
5275                          */
5276                         pstrcpy(fname, fsp->fsp_name);
5277                         if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) {
5278                                 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
5279                                 return UNIXERROR(ERRDOS,ERRbadpath);
5280                         }
5281                 } else if (fsp && fsp->print_file) {
5282                         /*
5283                          * Doing a DELETE_ON_CLOSE should cancel a print job.
5284                          */
5285                         if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
5286                                 fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
5287
5288                                 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
5289         
5290                                 SSVAL(params,0,0);
5291                                 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
5292                                 return(-1);
5293                         } else
5294                                 return (UNIXERROR(ERRDOS,ERRbadpath));
5295             } else {
5296                         /*
5297                          * Original code - this is an open file.
5298                          */
5299                         CHECK_FSP(fsp,conn);
5300
5301                         pstrcpy(fname, fsp->fsp_name);
5302
5303                         if (SMB_VFS_FSTAT(fsp, fsp->fh->fd, &sbuf) != 0) {
5304                                 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
5305                                 return(UNIXERROR(ERRDOS,ERRbadfid));
5306                         }
5307                 }
5308         } else {
5309                 /* set path info */
5310                 if (total_params < 7) {
5311                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5312                 }
5313
5314                 info_level = SVAL(params,0);    
5315                 srvstr_get_path(inbuf, fname, &params[6], sizeof(fname), total_params - 6, STR_TERMINATE, &status);
5316                 if (!NT_STATUS_IS_OK(status)) {
5317                         return ERROR_NT(status);
5318                 }
5319
5320                 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
5321
5322                 status = unix_convert(conn, fname, False, NULL, &sbuf);
5323                 if (!NT_STATUS_IS_OK(status)) {
5324                         return ERROR_NT(status);
5325                 }
5326
5327                 /*
5328                  * For CIFS UNIX extensions the target name may not exist.
5329                  */
5330
5331                 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
5332                         DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
5333                         return UNIXERROR(ERRDOS,ERRbadpath);
5334                 }    
5335
5336                 status = check_name(conn, fname);
5337                 if (!NT_STATUS_IS_OK(status)) {
5338                         return ERROR_NT(status);
5339                 }
5340
5341         }
5342
5343         if (!CAN_WRITE(conn)) {
5344                 return ERROR_DOS(ERRSRV,ERRaccess);
5345         }
5346
5347         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
5348                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
5349         }
5350
5351         DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
5352                 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
5353
5354         /* Realloc the parameter size */
5355         *pparams = (char *)SMB_REALLOC(*pparams,2);
5356         if (*pparams == NULL) {
5357                 return ERROR_NT(NT_STATUS_NO_MEMORY);
5358         }
5359         params = *pparams;
5360
5361         SSVAL(params,0,0);
5362
5363         if (fsp && fsp->pending_modtime) {
5364                 /* the pending modtime overrides the current modtime */
5365                 sbuf.st_mtime = fsp->pending_modtime;
5366         }
5367
5368         switch (info_level) {
5369
5370                 case SMB_INFO_STANDARD:
5371                 {
5372                         status = smb_set_info_standard(conn,
5373                                         pdata,
5374                                         total_data,
5375                                         fsp,
5376                                         fname,
5377                                         &sbuf);
5378                         break;
5379                 }
5380
5381                 case SMB_INFO_SET_EA:
5382                 {
5383                         status = smb_info_set_ea(conn,
5384                                                 pdata,
5385                                                 total_data,
5386                                                 fsp,
5387                                                 fname);
5388                         break;
5389                 }
5390
5391                 case SMB_SET_FILE_BASIC_INFO:
5392                 case SMB_FILE_BASIC_INFORMATION:
5393                 {
5394                         status = smb_set_file_basic_info(conn,
5395                                                         pdata,
5396                                                         total_data,
5397                                                         fsp,
5398                                                         fname,
5399                                                         &sbuf);
5400                         break;
5401                 }
5402
5403                 case SMB_FILE_ALLOCATION_INFORMATION:
5404                 case SMB_SET_FILE_ALLOCATION_INFO:
5405                 {
5406                         status = smb_set_file_allocation_info(conn,
5407                                                                 pdata,
5408                                                                 total_data,
5409                                                                 fsp,
5410                                                                 fname,
5411                                                                 &sbuf);
5412                         break;
5413                 }
5414
5415                 case SMB_FILE_END_OF_FILE_INFORMATION:
5416                 case SMB_SET_FILE_END_OF_FILE_INFO:
5417                 {
5418                         status = smb_set_file_end_of_file_info(conn,
5419                                                                 pdata,
5420                                                                 total_data,
5421                                                                 fsp,
5422                                                                 fname,
5423                                                                 &sbuf);
5424                         break;
5425                 }
5426
5427                 case SMB_FILE_DISPOSITION_INFORMATION:
5428                 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
5429                 {
5430 #if 0
5431                         /* JRA - We used to just ignore this on a path ? 
5432                          * Shouldn't this be invalid level on a pathname
5433                          * based call ?
5434                          */
5435                         if (tran_call != TRANSACT2_SETFILEINFO) {
5436                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
5437                         }
5438 #endif
5439                         status = smb_set_file_disposition_info(conn,
5440                                                 pdata,
5441                                                 total_data,
5442                                                 fsp,
5443                                                 fname,
5444                                                 &sbuf);
5445                         break;
5446                 }
5447
5448                 case SMB_FILE_POSITION_INFORMATION:
5449                 {
5450                         status = smb_file_position_information(conn,
5451                                                 pdata,
5452                                                 total_data,
5453                                                 fsp);
5454                         break;
5455                 }
5456
5457                 /* From tridge Samba4 : 
5458                  * MODE_INFORMATION in setfileinfo (I have no
5459                  * idea what "mode information" on a file is - it takes a value of 0,
5460                  * 2, 4 or 6. What could it be?).
5461                  */
5462
5463                 case SMB_FILE_MODE_INFORMATION:
5464                 {
5465                         status = smb_file_mode_information(conn,
5466                                                 pdata,
5467                                                 total_data);
5468                         break;
5469                 }
5470
5471                 /*
5472                  * CIFS UNIX extensions.
5473                  */
5474
5475                 case SMB_SET_FILE_UNIX_BASIC:
5476                 {
5477                         status = smb_set_file_unix_basic(conn,
5478                                                         pdata,
5479                                                         total_data,
5480                                                         fsp,
5481                                                         fname,
5482                                                         &sbuf);
5483                         break;
5484                 }
5485
5486                 case SMB_SET_FILE_UNIX_LINK:
5487                 {
5488                         if (tran_call != TRANSACT2_SETPATHINFO) {
5489                                 /* We must have a pathname for this. */
5490                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
5491                         }
5492                         status = smb_set_file_unix_link(conn,
5493                                                 inbuf,
5494                                                 pdata,
5495                                                 total_data,
5496                                                 fname);
5497                         break;
5498                 }
5499
5500                 case SMB_SET_FILE_UNIX_HLINK:
5501                 {
5502                         if (tran_call != TRANSACT2_SETPATHINFO) {
5503                                 /* We must have a pathname for this. */
5504                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
5505                         }
5506                         status = smb_set_file_unix_hlink(conn,
5507                                                 inbuf,
5508                                                 outbuf,
5509                                                 pdata,
5510                                                 total_data,
5511                                                 fname);
5512                         break;
5513                 }
5514
5515                 case SMB_FILE_RENAME_INFORMATION:
5516                 {
5517                         status = smb_file_rename_information(conn,
5518                                                         inbuf,
5519                                                         outbuf,
5520                                                         pdata,
5521                                                         total_data,
5522                                                         fsp,
5523                                                         fname);
5524                         break;
5525                 }
5526
5527 #if defined(HAVE_POSIX_ACLS)
5528                 case SMB_SET_POSIX_ACL:
5529                 {
5530                         status = smb_set_posix_acl(conn,
5531                                                 pdata,
5532                                                 total_data,
5533                                                 fsp,
5534                                                 fname,
5535                                                 &sbuf);
5536                         break;
5537                 }
5538 #endif
5539
5540                 case SMB_SET_POSIX_LOCK:
5541                 {
5542                         if (tran_call != TRANSACT2_SETFILEINFO) {
5543                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
5544                         }
5545                         status = smb_set_posix_lock(conn,
5546                                                 inbuf,
5547                                                 length,
5548                                                 pdata,
5549                                                 total_data,
5550                                                 fsp);
5551                         break;
5552                 }
5553
5554                 case SMB_POSIX_PATH_OPEN:
5555                 {
5556                         if (tran_call != TRANSACT2_SETPATHINFO) {
5557                                 /* We must have a pathname for this. */
5558                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
5559                         }
5560
5561                         status = smb_posix_open(conn,
5562                                                 ppdata,
5563                                                 total_data,
5564                                                 fname,
5565                                                 &sbuf,
5566                                                 &data_return_size);
5567                         break;
5568                 }
5569
5570                 case SMB_POSIX_PATH_UNLINK:
5571                 {
5572                         if (tran_call != TRANSACT2_SETPATHINFO) {
5573                                 /* We must have a pathname for this. */
5574                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
5575                         }
5576
5577                         status = smb_posix_unlink(conn,
5578                                                 pdata,
5579                                                 total_data,
5580                                                 fname,
5581                                                 &sbuf);
5582                         break;
5583                 }
5584
5585                 default:
5586                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
5587         }
5588
5589         
5590         if (!NT_STATUS_IS_OK(status)) {
5591                 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
5592                         /* We have re-scheduled this call. */
5593                         return -1;
5594                 }
5595                 if (blocking_lock_was_deferred(SVAL(inbuf,smb_mid))) {
5596                         /* We have re-scheduled this call. */
5597                         return -1;
5598                 }
5599                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5600                         return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
5601                 }
5602                 return ERROR_NT(status);
5603         }
5604
5605         SSVAL(params,0,0);
5606         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_return_size, max_data_bytes);
5607   
5608         return -1;
5609 }
5610
5611 /****************************************************************************
5612  Reply to a TRANS2_MKDIR (make directory with extended attributes).
5613 ****************************************************************************/
5614
5615 static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
5616                                         char **pparams, int total_params, char **ppdata, int total_data,
5617                                         unsigned int max_data_bytes)
5618 {
5619         char *params = *pparams;
5620         char *pdata = *ppdata;
5621         pstring directory;
5622         SMB_STRUCT_STAT sbuf;
5623         NTSTATUS status = NT_STATUS_OK;
5624         struct ea_list *ea_list = NULL;
5625
5626         if (!CAN_WRITE(conn))
5627                 return ERROR_DOS(ERRSRV,ERRaccess);
5628
5629         if (total_params < 5) {
5630                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5631         }
5632
5633         srvstr_get_path(inbuf, directory, &params[4], sizeof(directory), total_params - 4, STR_TERMINATE, &status);
5634         if (!NT_STATUS_IS_OK(status)) {
5635                 return ERROR_NT(status);
5636         }
5637
5638         DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
5639
5640         status = unix_convert(conn, directory, False, NULL, &sbuf);
5641         if (!NT_STATUS_IS_OK(status)) {
5642                 return ERROR_NT(status);
5643         }
5644
5645         /* Any data in this call is an EA list. */
5646         if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
5647                 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
5648         }
5649
5650         /*
5651          * OS/2 workplace shell seems to send SET_EA requests of "null"
5652          * length (4 bytes containing IVAL 4).
5653          * They seem to have no effect. Bug #3212. JRA.
5654          */
5655
5656         if (total_data != 4) {
5657                 if (total_data < 10) {
5658                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5659                 }
5660
5661                 if (IVAL(pdata,0) > total_data) {
5662                         DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
5663                                 IVAL(pdata,0), (unsigned int)total_data));
5664                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5665                 }
5666
5667                 ea_list = read_ea_list(tmp_talloc_ctx(), pdata + 4,
5668                                        total_data - 4);
5669                 if (!ea_list) {
5670                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5671                 }
5672         } else if (IVAL(pdata,0) != 4) {
5673                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5674         }
5675
5676         status = check_name(conn, directory);
5677         if (!NT_STATUS_IS_OK(status)) {
5678                 DEBUG(5,("call_trans2mkdir error (%s)\n", nt_errstr(status)));
5679                 return ERROR_NT(status);
5680         }
5681
5682         status = create_directory(conn, directory);
5683
5684         if (!NT_STATUS_IS_OK(status)) {
5685                 return ERROR_NT(status);
5686         }
5687   
5688         /* Try and set any given EA. */
5689         if (ea_list) {
5690                 status = set_ea(conn, NULL, directory, ea_list);
5691                 if (!NT_STATUS_IS_OK(status)) {
5692                         return ERROR_NT(status);
5693                 }
5694         }
5695
5696         /* Realloc the parameter and data sizes */
5697         *pparams = (char *)SMB_REALLOC(*pparams,2);
5698         if(*pparams == NULL) {
5699                 return ERROR_NT(NT_STATUS_NO_MEMORY);
5700         }
5701         params = *pparams;
5702
5703         SSVAL(params,0,0);
5704
5705         send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
5706   
5707         return(-1);
5708 }
5709
5710 /****************************************************************************
5711  Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
5712  We don't actually do this - we just send a null response.
5713 ****************************************************************************/
5714
5715 static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
5716                                         char **pparams, int total_params, char **ppdata, int total_data,
5717                                         unsigned int max_data_bytes)
5718 {
5719         static uint16 fnf_handle = 257;
5720         char *params = *pparams;
5721         uint16 info_level;
5722
5723         if (total_params < 6) {
5724                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5725         }
5726
5727         info_level = SVAL(params,4);
5728         DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
5729
5730         switch (info_level) {
5731                 case 1:
5732                 case 2:
5733                         break;
5734                 default:
5735                         return ERROR_NT(NT_STATUS_INVALID_LEVEL);
5736         }
5737
5738         /* Realloc the parameter and data sizes */
5739         *pparams = (char *)SMB_REALLOC(*pparams,6);
5740         if (*pparams == NULL) {
5741                 return ERROR_NT(NT_STATUS_NO_MEMORY);
5742         }
5743         params = *pparams;
5744
5745         SSVAL(params,0,fnf_handle);
5746         SSVAL(params,2,0); /* No changes */
5747         SSVAL(params,4,0); /* No EA errors */
5748
5749         fnf_handle++;
5750
5751         if(fnf_handle == 0)
5752                 fnf_handle = 257;
5753
5754         send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0, max_data_bytes);
5755   
5756         return(-1);
5757 }
5758
5759 /****************************************************************************
5760  Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for 
5761  changes). Currently this does nothing.
5762 ****************************************************************************/
5763
5764 static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
5765                                         char **pparams, int total_params, char **ppdata, int total_data,
5766                                         unsigned int max_data_bytes)
5767 {
5768         char *params = *pparams;
5769
5770         DEBUG(3,("call_trans2findnotifynext\n"));
5771
5772         /* Realloc the parameter and data sizes */
5773         *pparams = (char *)SMB_REALLOC(*pparams,4);
5774         if (*pparams == NULL) {
5775                 return ERROR_NT(NT_STATUS_NO_MEMORY);
5776         }
5777         params = *pparams;
5778
5779         SSVAL(params,0,0); /* No changes */
5780         SSVAL(params,2,0); /* No EA errors */
5781
5782         send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0, max_data_bytes);
5783   
5784         return(-1);
5785 }
5786
5787 /****************************************************************************
5788  Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
5789 ****************************************************************************/
5790
5791 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
5792                                         char **pparams, int total_params, char **ppdata, int total_data,
5793                                         unsigned int max_data_bytes)
5794 {
5795         char *params = *pparams;
5796         pstring pathname;
5797         int reply_size = 0;
5798         int max_referral_level;
5799
5800         DEBUG(10,("call_trans2getdfsreferral\n"));
5801
5802         if (total_params < 3) {
5803                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5804         }
5805
5806         max_referral_level = SVAL(params,0);
5807
5808         if(!lp_host_msdfs())
5809                 return ERROR_DOS(ERRDOS,ERRbadfunc);
5810
5811         srvstr_pull(inbuf, pathname, &params[2], sizeof(pathname), total_params - 2, STR_TERMINATE);
5812         if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
5813                 return UNIXERROR(ERRDOS,ERRbadfile);
5814     
5815         SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
5816         send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size, max_data_bytes);
5817
5818         return(-1);
5819 }
5820
5821 #define LMCAT_SPL       0x53
5822 #define LMFUNC_GETJOBID 0x60
5823
5824 /****************************************************************************
5825  Reply to a TRANS2_IOCTL - used for OS/2 printing.
5826 ****************************************************************************/
5827
5828 static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
5829                                         char **pparams, int total_params, char **ppdata, int total_data,
5830                                         unsigned int max_data_bytes)
5831 {
5832         char *pdata = *ppdata;
5833         files_struct *fsp = file_fsp(inbuf,smb_vwv15);
5834
5835         /* check for an invalid fid before proceeding */
5836         
5837         if (!fsp)                                
5838                 return(ERROR_DOS(ERRDOS,ERRbadfid));  
5839
5840         if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
5841                         (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
5842                 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
5843                 if (*ppdata == NULL) {
5844                         return ERROR_NT(NT_STATUS_NO_MEMORY);
5845                 }
5846                 pdata = *ppdata;
5847
5848                 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
5849                         CAN ACCEPT THIS IN UNICODE. JRA. */
5850
5851                 SSVAL(pdata,0,fsp->rap_print_jobid);                     /* Job number */
5852                 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
5853                 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
5854                 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32, max_data_bytes);
5855                 return(-1);
5856         } else {
5857                 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
5858                 return ERROR_DOS(ERRSRV,ERRerror);
5859         }
5860 }
5861
5862 /****************************************************************************
5863  Reply to a SMBfindclose (stop trans2 directory search).
5864 ****************************************************************************/
5865
5866 int reply_findclose(connection_struct *conn,
5867                     char *inbuf,char *outbuf,int length,int bufsize)
5868 {
5869         int outsize = 0;
5870         int dptr_num=SVALS(inbuf,smb_vwv0);
5871         START_PROFILE(SMBfindclose);
5872
5873         DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
5874
5875         dptr_close(&dptr_num);
5876
5877         outsize = set_message(outbuf,0,0,False);
5878
5879         DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
5880
5881         END_PROFILE(SMBfindclose);
5882         return(outsize);
5883 }
5884
5885 /****************************************************************************
5886  Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
5887 ****************************************************************************/
5888
5889 int reply_findnclose(connection_struct *conn, 
5890                      char *inbuf,char *outbuf,int length,int bufsize)
5891 {
5892         int outsize = 0;
5893         int dptr_num= -1;
5894         START_PROFILE(SMBfindnclose);
5895         
5896         dptr_num = SVAL(inbuf,smb_vwv0);
5897
5898         DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
5899
5900         /* We never give out valid handles for a 
5901            findnotifyfirst - so any dptr_num is ok here. 
5902            Just ignore it. */
5903
5904         outsize = set_message(outbuf,0,0,False);
5905
5906         DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
5907
5908         END_PROFILE(SMBfindnclose);
5909         return(outsize);
5910 }
5911
5912 int handle_trans2(connection_struct *conn,
5913                   struct trans_state *state,
5914                   char *inbuf, char *outbuf, int size, int bufsize)
5915 {
5916         int outsize;
5917
5918         if (Protocol >= PROTOCOL_NT1) {
5919                 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
5920         }
5921
5922         /* Now we must call the relevant TRANS2 function */
5923         switch(state->call)  {
5924         case TRANSACT2_OPEN:
5925         {
5926                 START_PROFILE(Trans2_open);
5927                 outsize = call_trans2open(
5928                         conn, inbuf, outbuf, bufsize, 
5929                         &state->param, state->total_param,
5930                         &state->data, state->total_data,
5931                         state->max_data_return);
5932                 END_PROFILE(Trans2_open);
5933                 break;
5934         }
5935
5936         case TRANSACT2_FINDFIRST:
5937         {
5938                 START_PROFILE(Trans2_findfirst);
5939                 outsize = call_trans2findfirst(
5940                         conn, inbuf, outbuf, bufsize,
5941                         &state->param, state->total_param,
5942                         &state->data, state->total_data,
5943                         state->max_data_return);
5944                 END_PROFILE(Trans2_findfirst);
5945                 break;
5946         }
5947
5948         case TRANSACT2_FINDNEXT:
5949         {
5950                 START_PROFILE(Trans2_findnext);
5951                 outsize = call_trans2findnext(
5952                         conn, inbuf, outbuf, size, bufsize, 
5953                         &state->param, state->total_param,
5954                         &state->data, state->total_data,
5955                         state->max_data_return);
5956                 END_PROFILE(Trans2_findnext);
5957                 break;
5958         }
5959
5960         case TRANSACT2_QFSINFO:
5961         {
5962                 START_PROFILE(Trans2_qfsinfo);
5963                 outsize = call_trans2qfsinfo(
5964                         conn, inbuf, outbuf, size, bufsize,
5965                         &state->param, state->total_param,
5966                         &state->data, state->total_data,
5967                         state->max_data_return);
5968                 END_PROFILE(Trans2_qfsinfo);
5969             break;
5970         }
5971
5972         case TRANSACT2_SETFSINFO:
5973         {
5974                 START_PROFILE(Trans2_setfsinfo);
5975                 outsize = call_trans2setfsinfo(
5976                         conn, inbuf, outbuf, size, bufsize, 
5977                         &state->param, state->total_param,
5978                         &state->data, state->total_data,
5979                         state->max_data_return);
5980                 END_PROFILE(Trans2_setfsinfo);
5981                 break;
5982         }
5983
5984         case TRANSACT2_QPATHINFO:
5985         case TRANSACT2_QFILEINFO:
5986         {
5987                 START_PROFILE(Trans2_qpathinfo);
5988                 outsize = call_trans2qfilepathinfo(
5989                         conn, inbuf, outbuf, size, bufsize, state->call,
5990                         &state->param, state->total_param,
5991                         &state->data, state->total_data,
5992                         state->max_data_return);
5993                 END_PROFILE(Trans2_qpathinfo);
5994                 break;
5995         }
5996
5997         case TRANSACT2_SETPATHINFO:
5998         case TRANSACT2_SETFILEINFO:
5999         {
6000                 START_PROFILE(Trans2_setpathinfo);
6001                 outsize = call_trans2setfilepathinfo(
6002                         conn, inbuf, outbuf, size, bufsize, state->call,
6003                         &state->param, state->total_param,
6004                         &state->data, state->total_data,
6005                         state->max_data_return);
6006                 END_PROFILE(Trans2_setpathinfo);
6007                 break;
6008         }
6009
6010         case TRANSACT2_FINDNOTIFYFIRST:
6011         {
6012                 START_PROFILE(Trans2_findnotifyfirst);
6013                 outsize = call_trans2findnotifyfirst(
6014                         conn, inbuf, outbuf, size, bufsize, 
6015                         &state->param, state->total_param,
6016                         &state->data, state->total_data,
6017                         state->max_data_return);
6018                 END_PROFILE(Trans2_findnotifyfirst);
6019                 break;
6020         }
6021
6022         case TRANSACT2_FINDNOTIFYNEXT:
6023         {
6024                 START_PROFILE(Trans2_findnotifynext);
6025                 outsize = call_trans2findnotifynext(
6026                         conn, inbuf, outbuf, size, bufsize, 
6027                         &state->param, state->total_param,
6028                         &state->data, state->total_data,
6029                         state->max_data_return);
6030                 END_PROFILE(Trans2_findnotifynext);
6031                 break;
6032         }
6033
6034         case TRANSACT2_MKDIR:
6035         {
6036                 START_PROFILE(Trans2_mkdir);
6037                 outsize = call_trans2mkdir(
6038                         conn, inbuf, outbuf, size, bufsize,
6039                         &state->param, state->total_param,
6040                         &state->data, state->total_data,
6041                         state->max_data_return);
6042                 END_PROFILE(Trans2_mkdir);
6043                 break;
6044         }
6045
6046         case TRANSACT2_GET_DFS_REFERRAL:
6047         {
6048                 START_PROFILE(Trans2_get_dfs_referral);
6049                 outsize = call_trans2getdfsreferral(
6050                         conn, inbuf, outbuf, size, bufsize,
6051                         &state->param, state->total_param,
6052                         &state->data, state->total_data,
6053                         state->max_data_return);
6054                 END_PROFILE(Trans2_get_dfs_referral);
6055                 break;
6056         }
6057
6058         case TRANSACT2_IOCTL:
6059         {
6060                 START_PROFILE(Trans2_ioctl);
6061                 outsize = call_trans2ioctl(
6062                         conn, inbuf, outbuf, size, bufsize,
6063                         &state->param, state->total_param,
6064                         &state->data, state->total_data,
6065                         state->max_data_return);
6066                 END_PROFILE(Trans2_ioctl);
6067                 break;
6068         }
6069
6070         default:
6071                 /* Error in request */
6072                 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
6073                 outsize = ERROR_DOS(ERRSRV,ERRerror);
6074         }
6075
6076         return outsize;
6077 }
6078
6079 /****************************************************************************
6080  Reply to a SMBtrans2.
6081  ****************************************************************************/
6082
6083 int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf,
6084                  int size, int bufsize)
6085 {
6086         int outsize = 0;
6087         unsigned int dsoff = SVAL(inbuf, smb_dsoff);
6088         unsigned int dscnt = SVAL(inbuf, smb_dscnt);
6089         unsigned int psoff = SVAL(inbuf, smb_psoff);
6090         unsigned int pscnt = SVAL(inbuf, smb_pscnt);
6091         unsigned int tran_call = SVAL(inbuf, smb_setup0);
6092         struct trans_state *state;
6093         NTSTATUS result;
6094
6095         START_PROFILE(SMBtrans2);
6096
6097         result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid));
6098         if (!NT_STATUS_IS_OK(result)) {
6099                 DEBUG(2, ("Got invalid trans2 request: %s\n",
6100                           nt_errstr(result)));
6101                 END_PROFILE(SMBtrans2);
6102                 return ERROR_NT(result);
6103         }
6104
6105         if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
6106             && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
6107                 END_PROFILE(SMBtrans2);
6108                 return ERROR_DOS(ERRSRV,ERRaccess);
6109         }
6110
6111         if ((state = TALLOC_P(conn->mem_ctx, struct trans_state)) == NULL) {
6112                 DEBUG(0, ("talloc failed\n"));
6113                 END_PROFILE(SMBtrans2);
6114                 return ERROR_NT(NT_STATUS_NO_MEMORY);
6115         }
6116
6117         state->cmd = SMBtrans2;
6118
6119         state->mid = SVAL(inbuf, smb_mid);
6120         state->vuid = SVAL(inbuf, smb_uid);
6121         state->setup_count = SVAL(inbuf, smb_suwcnt);
6122         state->setup = NULL;
6123         state->total_param = SVAL(inbuf, smb_tpscnt);
6124         state->param = NULL;
6125         state->total_data =  SVAL(inbuf, smb_tdscnt);
6126         state->data = NULL;
6127         state->max_param_return = SVAL(inbuf, smb_mprcnt);
6128         state->max_data_return  = SVAL(inbuf, smb_mdrcnt);
6129         state->max_setup_return = SVAL(inbuf, smb_msrcnt);
6130         state->close_on_completion = BITSETW(inbuf+smb_vwv5,0);
6131         state->one_way = BITSETW(inbuf+smb_vwv5,1);
6132
6133         state->call = tran_call;
6134
6135         /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
6136            is so as a sanity check */
6137         if (state->setup_count != 1) {
6138                 /*
6139                  * Need to have rc=0 for ioctl to get job id for OS/2.
6140                  *  Network printing will fail if function is not successful.
6141                  *  Similar function in reply.c will be used if protocol
6142                  *  is LANMAN1.0 instead of LM1.2X002.
6143                  *  Until DosPrintSetJobInfo with PRJINFO3 is supported,
6144                  *  outbuf doesn't have to be set(only job id is used).
6145                  */
6146                 if ( (state->setup_count == 4) && (tran_call == TRANSACT2_IOCTL) &&
6147                                 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
6148                                 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
6149                         DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
6150                 } else {
6151                         DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
6152                         DEBUG(2,("Transaction is %d\n",tran_call));
6153                         TALLOC_FREE(state);
6154                         END_PROFILE(SMBtrans2);
6155                         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
6156                 }
6157         }
6158
6159         if ((dscnt > state->total_data) || (pscnt > state->total_param))
6160                 goto bad_param;
6161
6162         if (state->total_data) {
6163                 /* Can't use talloc here, the core routines do realloc on the
6164                  * params and data. */
6165                 state->data = (char *)SMB_MALLOC(state->total_data);
6166                 if (state->data == NULL) {
6167                         DEBUG(0,("reply_trans2: data malloc fail for %u "
6168                                  "bytes !\n", (unsigned int)state->total_data));
6169                         TALLOC_FREE(state);
6170                         END_PROFILE(SMBtrans2);
6171                         return(ERROR_DOS(ERRDOS,ERRnomem));
6172                 }
6173                 if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
6174                         goto bad_param;
6175                 if ((smb_base(inbuf)+dsoff+dscnt > inbuf + size) ||
6176                     (smb_base(inbuf)+dsoff+dscnt < smb_base(inbuf)))
6177                         goto bad_param;
6178
6179                 memcpy(state->data,smb_base(inbuf)+dsoff,dscnt);
6180         }
6181
6182         if (state->total_param) {
6183                 /* Can't use talloc here, the core routines do realloc on the
6184                  * params and data. */
6185                 state->param = (char *)SMB_MALLOC(state->total_param);
6186                 if (state->param == NULL) {
6187                         DEBUG(0,("reply_trans: param malloc fail for %u "
6188                                  "bytes !\n", (unsigned int)state->total_param));
6189                         SAFE_FREE(state->data);
6190                         TALLOC_FREE(state);
6191                         END_PROFILE(SMBtrans2);
6192                         return(ERROR_DOS(ERRDOS,ERRnomem));
6193                 } 
6194                 if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt))
6195                         goto bad_param;
6196                 if ((smb_base(inbuf)+psoff+pscnt > inbuf + size) ||
6197                     (smb_base(inbuf)+psoff+pscnt < smb_base(inbuf)))
6198                         goto bad_param;
6199
6200                 memcpy(state->param,smb_base(inbuf)+psoff,pscnt);
6201         }
6202
6203         state->received_data  = dscnt;
6204         state->received_param = pscnt;
6205
6206         if ((state->received_param == state->total_param) &&
6207             (state->received_data == state->total_data)) {
6208
6209                 outsize = handle_trans2(conn, state, inbuf, outbuf,
6210                                         size, bufsize);
6211                 SAFE_FREE(state->data);
6212                 SAFE_FREE(state->param);
6213                 TALLOC_FREE(state);
6214                 END_PROFILE(SMBtrans2);
6215                 return outsize;
6216         }
6217
6218         DLIST_ADD(conn->pending_trans, state);
6219
6220         /* We need to send an interim response then receive the rest
6221            of the parameter/data bytes */
6222         outsize = set_message(outbuf,0,0,False);
6223         show_msg(outbuf);
6224         END_PROFILE(SMBtrans2);
6225         return outsize;
6226
6227   bad_param:
6228
6229         DEBUG(0,("reply_trans2: invalid trans parameters\n"));
6230         SAFE_FREE(state->data);
6231         SAFE_FREE(state->param);
6232         TALLOC_FREE(state);
6233         END_PROFILE(SMBtrans2);
6234         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
6235 }
6236
6237
6238 /****************************************************************************
6239  Reply to a SMBtranss2
6240  ****************************************************************************/
6241
6242 int reply_transs2(connection_struct *conn,
6243                   char *inbuf,char *outbuf,int size,int bufsize)
6244 {
6245         int outsize = 0;
6246         unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
6247         struct trans_state *state;
6248
6249         START_PROFILE(SMBtranss2);
6250
6251         show_msg(inbuf);
6252
6253         for (state = conn->pending_trans; state != NULL;
6254              state = state->next) {
6255                 if (state->mid == SVAL(inbuf,smb_mid)) {
6256                         break;
6257                 }
6258         }
6259
6260         if ((state == NULL) || (state->cmd != SMBtrans2)) {
6261                 END_PROFILE(SMBtranss2);
6262                 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
6263         }
6264
6265         /* Revise state->total_param and state->total_data in case they have
6266            changed downwards */
6267
6268         if (SVAL(inbuf, smb_tpscnt) < state->total_param)
6269                 state->total_param = SVAL(inbuf, smb_tpscnt);
6270         if (SVAL(inbuf, smb_tdscnt) < state->total_data)
6271                 state->total_data = SVAL(inbuf, smb_tdscnt);
6272
6273         pcnt = SVAL(inbuf, smb_spscnt);
6274         poff = SVAL(inbuf, smb_spsoff);
6275         pdisp = SVAL(inbuf, smb_spsdisp);
6276
6277         dcnt = SVAL(inbuf, smb_sdscnt);
6278         doff = SVAL(inbuf, smb_sdsoff);
6279         ddisp = SVAL(inbuf, smb_sdsdisp);
6280
6281         state->received_param += pcnt;
6282         state->received_data += dcnt;
6283                 
6284         if ((state->received_data > state->total_data) ||
6285             (state->received_param > state->total_param))
6286                 goto bad_param;
6287
6288         if (pcnt) {
6289                 if (pdisp+pcnt > state->total_param)
6290                         goto bad_param;
6291                 if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt))
6292                         goto bad_param;
6293                 if (pdisp > state->total_param)
6294                         goto bad_param;
6295                 if ((smb_base(inbuf) + poff + pcnt > inbuf + size) ||
6296                     (smb_base(inbuf) + poff + pcnt < smb_base(inbuf)))
6297                         goto bad_param;
6298                 if (state->param + pdisp < state->param)
6299                         goto bad_param;
6300
6301                 memcpy(state->param+pdisp,smb_base(inbuf)+poff,
6302                        pcnt);
6303         }
6304
6305         if (dcnt) {
6306                 if (ddisp+dcnt > state->total_data)
6307                         goto bad_param;
6308                 if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt))
6309                         goto bad_param;
6310                 if (ddisp > state->total_data)
6311                         goto bad_param;
6312                 if ((smb_base(inbuf) + doff + dcnt > inbuf + size) ||
6313                     (smb_base(inbuf) + doff + dcnt < smb_base(inbuf)))
6314                         goto bad_param;
6315                 if (state->data + ddisp < state->data)
6316                         goto bad_param;
6317
6318                 memcpy(state->data+ddisp, smb_base(inbuf)+doff,
6319                        dcnt);      
6320         }
6321
6322         if ((state->received_param < state->total_param) ||
6323             (state->received_data < state->total_data)) {
6324                 END_PROFILE(SMBtranss2);
6325                 return -1;
6326         }
6327
6328         /* construct_reply_common has done us the favor to pre-fill the
6329          * command field with SMBtranss2 which is wrong :-)
6330          */
6331         SCVAL(outbuf,smb_com,SMBtrans2);
6332
6333         outsize = handle_trans2(conn, state, inbuf, outbuf, size, bufsize);
6334
6335         DLIST_REMOVE(conn->pending_trans, state);
6336         SAFE_FREE(state->data);
6337         SAFE_FREE(state->param);
6338         TALLOC_FREE(state);
6339
6340         if (outsize == 0) {
6341                 END_PROFILE(SMBtranss2);
6342                 return(ERROR_DOS(ERRSRV,ERRnosupport));
6343         }
6344         
6345         END_PROFILE(SMBtranss2);
6346         return(outsize);
6347
6348   bad_param:
6349
6350         DEBUG(0,("reply_transs2: invalid trans parameters\n"));
6351         DLIST_REMOVE(conn->pending_trans, state);
6352         SAFE_FREE(state->data);
6353         SAFE_FREE(state->param);
6354         TALLOC_FREE(state);
6355         END_PROFILE(SMBtranss2);
6356         return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
6357 }