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