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