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