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