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