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