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