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