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