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