smbd: vfs: convert link_contents arg of SMB_VFS_SYMLINKAT() to struct smb_filename
[gd/samba-autobuild/.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                 0,              /* root_dir_fid */
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                 0,                                      /* root_dir_fid */
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                 /* Ensure we don't have a directory name of "". */
2886                 directory = talloc_strdup(talloc_tos(), ".");
2887                 if (!directory) {
2888                         reply_nterror(req, NT_STATUS_NO_MEMORY);
2889                         goto out;
2890                 }
2891                 /* Ensure smb_dname->base_name matches. */
2892                 smb_dname->base_name = directory;
2893         }
2894
2895         DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
2896
2897         if (info_level == SMB_FIND_EA_LIST) {
2898                 uint32_t ea_size;
2899
2900                 if (total_data < 4) {
2901                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2902                         goto out;
2903                 }
2904
2905                 ea_size = IVAL(pdata,0);
2906                 if (ea_size != total_data) {
2907                         DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2908 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2909                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2910                         goto out;
2911                 }
2912
2913                 if (!lp_ea_support(SNUM(conn))) {
2914                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
2915                         goto out;
2916                 }
2917
2918                 /* Pull out the list of names. */
2919                 ea_list = read_ea_name_list(talloc_tos(), pdata + 4, ea_size - 4);
2920                 if (!ea_list) {
2921                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2922                         goto out;
2923                 }
2924         }
2925
2926         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
2927                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2928                 goto out;
2929         }
2930
2931         *ppdata = (char *)SMB_REALLOC(
2932                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2933         if(*ppdata == NULL ) {
2934                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2935                 goto out;
2936         }
2937         pdata = *ppdata;
2938         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2939         /*
2940          * squash valgrind "writev(vector[...]) points to uninitialised byte(s)"
2941          * error.
2942          */
2943         memset(pdata + total_data, 0, ((max_data_bytes + DIR_ENTRY_SAFETY_MARGIN) - total_data));
2944         /* Realloc the params space */
2945         *pparams = (char *)SMB_REALLOC(*pparams, 10);
2946         if (*pparams == NULL) {
2947                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2948                 goto out;
2949         }
2950         params = *pparams;
2951
2952         /*
2953          * As we've cut off the last component from
2954          * smb_fname we need to re-stat smb_dname
2955          * so FILE_OPEN disposition knows the directory
2956          * exists.
2957          */
2958         if (req->posix_pathnames) {
2959                 ret = SMB_VFS_LSTAT(conn, smb_dname);
2960         } else {
2961                 ret = SMB_VFS_STAT(conn, smb_dname);
2962         }
2963
2964         if (ret == -1) {
2965                 ntstatus = map_nt_error_from_unix(errno);
2966                 reply_nterror(req, ntstatus);
2967                 goto out;
2968         }
2969
2970         /*
2971          * Open an fsp on this directory for the dptr.
2972          */
2973         ntstatus = SMB_VFS_CREATE_FILE(
2974                         conn, /* conn */
2975                         req, /* req */
2976                         0, /* root_dir_fid */
2977                         smb_dname, /* dname */
2978                         FILE_LIST_DIRECTORY, /* access_mask */
2979                         FILE_SHARE_READ|
2980                         FILE_SHARE_WRITE, /* share_access */
2981                         FILE_OPEN, /* create_disposition*/
2982                         FILE_DIRECTORY_FILE, /* create_options */
2983                         FILE_ATTRIBUTE_DIRECTORY,/* file_attributes */
2984                         NO_OPLOCK, /* oplock_request */
2985                         NULL, /* lease */
2986                         0, /* allocation_size */
2987                         0, /* private_flags */
2988                         NULL, /* sd */
2989                         NULL, /* ea_list */
2990                         &fsp, /* result */
2991                         NULL, /* pinfo */
2992                         NULL, /* in_context */
2993                         NULL);/* out_context */
2994
2995         if (!NT_STATUS_IS_OK(ntstatus)) {
2996                 DBG_ERR("failed to open directory %s\n",
2997                         smb_fname_str_dbg(smb_dname));
2998                 reply_nterror(req, ntstatus);
2999                 goto out;
3000         }
3001
3002         /* Save the wildcard match and attribs we are using on this directory -
3003                 needed as lanman2 assumes these are being saved between calls */
3004
3005         ntstatus = dptr_create(conn,
3006                                 req,
3007                                 fsp, /* fsp */
3008                                 False,
3009                                 True,
3010                                 req->smbpid,
3011                                 mask,
3012                                 mask_contains_wcard,
3013                                 dirtype,
3014                                 &fsp->dptr);
3015
3016         if (!NT_STATUS_IS_OK(ntstatus)) {
3017                 /*
3018                  * Use NULL here for the first parameter (req)
3019                  * as this is not a client visible handle so
3020                  * can'tbe part of an SMB1 chain.
3021                  */
3022                 close_file(NULL, fsp, NORMAL_CLOSE);
3023                 fsp = NULL;
3024                 reply_nterror(req, ntstatus);
3025                 goto out;
3026         }
3027
3028         if (backup_priv) {
3029                 /* Remember this in case we have
3030                    to do a findnext. */
3031                 dptr_set_priv(fsp->dptr);
3032         }
3033
3034         dptr_num = dptr_dnum(fsp->dptr);
3035         DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
3036
3037         /* We don't need to check for VOL here as this is returned by
3038                 a different TRANS2 call. */
3039
3040         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
3041                  directory,lp_dont_descend(talloc_tos(), lp_sub, SNUM(conn))));
3042         if (in_list(directory,
3043                     lp_dont_descend(talloc_tos(), lp_sub, SNUM(conn)),
3044                         conn->case_sensitive)) {
3045                 dont_descend = True;
3046         }
3047
3048         p = pdata;
3049         space_remaining = max_data_bytes;
3050         out_of_space = False;
3051
3052         for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
3053                 bool got_exact_match = False;
3054
3055                 /* this is a heuristic to avoid seeking the dirptr except when
3056                         absolutely necessary. It allows for a filename of about 40 chars */
3057                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
3058                         out_of_space = True;
3059                         finished = False;
3060                 } else {
3061                         ntstatus = get_lanman2_dir_entry(talloc_tos(),
3062                                         conn,
3063                                         fsp->dptr,
3064                                         req->flags2,
3065                                         mask,dirtype,info_level,
3066                                         requires_resume_key,dont_descend,
3067                                         ask_sharemode,
3068                                         &p,pdata,data_end,
3069                                         space_remaining,
3070                                         &got_exact_match,
3071                                         &last_entry_off, ea_list);
3072                         if (NT_STATUS_EQUAL(ntstatus,
3073                                         NT_STATUS_ILLEGAL_CHARACTER)) {
3074                                 /*
3075                                  * Bad character conversion on name. Ignore this
3076                                  * entry.
3077                                  */
3078                                 continue;
3079                         }
3080                         if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
3081                                 out_of_space = true;
3082                         } else {
3083                                 finished = !NT_STATUS_IS_OK(ntstatus);
3084                         }
3085                 }
3086
3087                 if (!finished && !out_of_space)
3088                         numentries++;
3089
3090                 /*
3091                  * As an optimisation if we know we aren't looking
3092                  * for a wildcard name (ie. the name matches the wildcard exactly)
3093                  * then we can finish on any (first) match.
3094                  * This speeds up large directory searches. JRA.
3095                  */
3096
3097                 if(got_exact_match)
3098                         finished = True;
3099
3100                 /* Ensure space_remaining never goes -ve. */
3101                 if (PTR_DIFF(p,pdata) > max_data_bytes) {
3102                         space_remaining = 0;
3103                         out_of_space = true;
3104                 } else {
3105                         space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
3106                 }
3107         }
3108
3109         /* Check if we can close the dirptr */
3110         if(close_after_first || (finished && close_if_end)) {
3111                 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
3112                 dptr_num = -1;
3113                 close_file(NULL, fsp, NORMAL_CLOSE);
3114                 fsp = NULL;
3115         }
3116
3117         /*
3118          * If there are no matching entries we must return ERRDOS/ERRbadfile -
3119          * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
3120          * the protocol level is less than NT1. Tested with smbclient. JRA.
3121          * This should fix the OS/2 client bug #2335.
3122          */
3123
3124         if(numentries == 0) {
3125                 dptr_num = -1;
3126                 /*
3127                  * We may have already closed the file in the
3128                  * close_after_first or finished case above.
3129                  */
3130                 if (fsp != NULL) {
3131                         close_file(NULL, fsp, NORMAL_CLOSE);
3132                         fsp = NULL;
3133                 }
3134                 if (get_Protocol() < PROTOCOL_NT1) {
3135                         reply_force_doserror(req, ERRDOS, ERRnofiles);
3136                         goto out;
3137                 } else {
3138                         reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
3139                                         ERRDOS, ERRbadfile);
3140                         goto out;
3141                 }
3142         }
3143
3144         /* At this point pdata points to numentries directory entries. */
3145
3146         /* Set up the return parameter block */
3147         SSVAL(params,0,dptr_num);
3148         SSVAL(params,2,numentries);
3149         SSVAL(params,4,finished);
3150         SSVAL(params,6,0); /* Never an EA error */
3151         SSVAL(params,8,last_entry_off);
3152
3153         send_trans2_replies(conn, req, NT_STATUS_OK, params, 10, pdata, PTR_DIFF(p,pdata),
3154                             max_data_bytes);
3155
3156         if ((! *directory) && dptr_path(sconn, dptr_num)) {
3157                 directory = talloc_strdup(talloc_tos(),dptr_path(sconn, dptr_num));
3158                 if (!directory) {
3159                         reply_nterror(req, NT_STATUS_NO_MEMORY);
3160                 }
3161         }
3162
3163         DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
3164                 smb_fn_name(req->cmd),
3165                 mask, directory, dirtype, numentries ) );
3166
3167         /*
3168          * Force a name mangle here to ensure that the
3169          * mask as an 8.3 name is top of the mangled cache.
3170          * The reasons for this are subtle. Don't remove
3171          * this code unless you know what you are doing
3172          * (see PR#13758). JRA.
3173          */
3174
3175         if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
3176                 char mangled_name[13];
3177                 name_to_8_3(mask, mangled_name, True, conn->params);
3178         }
3179  out:
3180
3181         if (as_root) {
3182                 unbecome_root();
3183         }
3184
3185         TALLOC_FREE(smb_dname);
3186         return;
3187 }
3188
3189 /****************************************************************************
3190  Reply to a TRANS2_FINDNEXT.
3191 ****************************************************************************/
3192
3193 static void call_trans2findnext(connection_struct *conn,
3194                                 struct smb_request *req,
3195                                 char **pparams, int total_params,
3196                                 char **ppdata, int total_data,
3197                                 unsigned int max_data_bytes)
3198 {
3199         /* We must be careful here that we don't return more than the
3200                 allowed number of data bytes. If this means returning fewer than
3201                 maxentries then so be it. We assume that the redirector has
3202                 enough room for the fixed number of parameter bytes it has
3203                 requested. */
3204         char *params = *pparams;
3205         char *pdata = *ppdata;
3206         char *data_end;
3207         int dptr_num;
3208         int maxentries;
3209         uint16_t info_level;
3210         uint32_t resume_key;
3211         uint16_t findnext_flags;
3212         bool close_after_request;
3213         bool close_if_end;
3214         bool requires_resume_key;
3215         bool continue_bit;
3216         bool mask_contains_wcard = False;
3217         char *resume_name = NULL;
3218         const char *mask = NULL;
3219         const char *directory = NULL;
3220         char *p = NULL;
3221         uint16_t dirtype;
3222         int numentries = 0;
3223         int i, last_entry_off=0;
3224         bool finished = False;
3225         bool dont_descend = False;
3226         bool out_of_space = False;
3227         int space_remaining;
3228         struct ea_list *ea_list = NULL;
3229         NTSTATUS ntstatus = NT_STATUS_OK;
3230         bool ask_sharemode = lp_smbd_search_ask_sharemode(SNUM(conn));
3231         TALLOC_CTX *ctx = talloc_tos();
3232         struct smbd_server_connection *sconn = req->sconn;
3233         bool backup_priv = false; 
3234         bool as_root = false;
3235         files_struct *fsp = NULL;
3236         const struct loadparm_substitution *lp_sub =
3237                 loadparm_s3_global_substitution();
3238
3239         if (total_params < 13) {
3240                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3241                 return;
3242         }
3243
3244         dptr_num = SVAL(params,0);
3245         maxentries = SVAL(params,2);
3246         info_level = SVAL(params,4);
3247         resume_key = IVAL(params,6);
3248         findnext_flags = SVAL(params,10);
3249         close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
3250         close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
3251         requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
3252         continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
3253
3254         if (!continue_bit) {
3255                 /* We only need resume_name if continue_bit is zero. */
3256                 if (req->posix_pathnames) {
3257                         srvstr_get_path_wcard_posix(ctx,
3258                                 params,
3259                                 req->flags2,
3260                                 &resume_name,
3261                                 params+12,
3262                                 total_params - 12,
3263                                 STR_TERMINATE,
3264                                 &ntstatus,
3265                                 &mask_contains_wcard);
3266                 } else {
3267                         srvstr_get_path_wcard(ctx,
3268                                 params,
3269                                 req->flags2,
3270                                 &resume_name,
3271                                 params+12,
3272                                 total_params - 12,
3273                                 STR_TERMINATE,
3274                                 &ntstatus,
3275                                 &mask_contains_wcard);
3276                 }
3277                 if (!NT_STATUS_IS_OK(ntstatus)) {
3278                         /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
3279                            complain (it thinks we're asking for the directory above the shared
3280                            path or an invalid name). Catch this as the resume name is only compared, never used in
3281                            a file access. JRA. */
3282                         srvstr_pull_talloc(ctx, params, req->flags2,
3283                                 &resume_name, params+12,
3284                                 total_params - 12,
3285                                 STR_TERMINATE);
3286
3287                         if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
3288                                 reply_nterror(req, ntstatus);
3289                                 return;
3290                         }
3291                 }
3292         }
3293
3294         DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
3295 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
3296 resume_key = %d resume name = %s continue=%d level = %d\n",
3297                 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end, 
3298                 requires_resume_key, resume_key,
3299                 resume_name ? resume_name : "(NULL)", continue_bit, info_level));
3300
3301         if (!maxentries) {
3302                 /* W2K3 seems to treat zero as 1. */
3303                 maxentries = 1;
3304         }
3305
3306         switch (info_level) {
3307                 case SMB_FIND_INFO_STANDARD:
3308                 case SMB_FIND_EA_SIZE:
3309                 case SMB_FIND_EA_LIST:
3310                 case SMB_FIND_FILE_DIRECTORY_INFO:
3311                 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
3312                 case SMB_FIND_FILE_NAMES_INFO:
3313                 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
3314                 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
3315                 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
3316                         break;
3317                 case SMB_FIND_FILE_UNIX:
3318                 case SMB_FIND_FILE_UNIX_INFO2:
3319                         /* Always use filesystem for UNIX mtime query. */
3320                         ask_sharemode = false;
3321                         if (!lp_unix_extensions()) {
3322                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3323                                 return;
3324                         }
3325                         break;
3326                 default:
3327                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3328                         return;
3329         }
3330
3331         if (info_level == SMB_FIND_EA_LIST) {
3332                 uint32_t ea_size;
3333
3334                 if (total_data < 4) {
3335                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3336                         return;
3337                 }
3338
3339                 ea_size = IVAL(pdata,0);
3340                 if (ea_size != total_data) {
3341                         DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
3342 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
3343                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3344                         return;
3345                 }
3346
3347                 if (!lp_ea_support(SNUM(conn))) {
3348                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
3349                         return;
3350                 }
3351
3352                 /* Pull out the list of names. */
3353                 ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
3354                 if (!ea_list) {
3355                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3356                         return;
3357                 }
3358         }
3359
3360         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
3361                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3362                 return;
3363         }
3364
3365         *ppdata = (char *)SMB_REALLOC(
3366                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
3367         if(*ppdata == NULL) {
3368                 reply_nterror(req, NT_STATUS_NO_MEMORY);
3369                 return;
3370         }
3371
3372         pdata = *ppdata;
3373         data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
3374
3375         /*
3376          * squash valgrind "writev(vector[...]) points to uninitialised byte(s)"
3377          * error.
3378          */
3379         memset(pdata + total_data, 0, (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN) - total_data);
3380         /* Realloc the params space */
3381         *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
3382         if(*pparams == NULL ) {
3383                 reply_nterror(req, NT_STATUS_NO_MEMORY);
3384                 return;
3385         }
3386
3387         params = *pparams;
3388
3389         /* Check that the dptr is valid */
3390         fsp = dptr_fetch_lanman2_fsp(sconn, dptr_num);
3391         if (fsp == NULL) {
3392                 reply_nterror(req, STATUS_NO_MORE_FILES);
3393                 return;
3394         }
3395
3396         directory = dptr_path(sconn, dptr_num);
3397
3398         /* Get the wildcard mask from the dptr */
3399         if((mask = dptr_wcard(sconn, dptr_num))== NULL) {
3400                 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
3401                 reply_nterror(req, STATUS_NO_MORE_FILES);
3402                 return;
3403         }
3404
3405         /* Get the attr mask from the dptr */
3406         dirtype = dptr_attr(sconn, dptr_num);
3407
3408         backup_priv = dptr_get_priv(fsp->dptr);
3409
3410         DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld) "
3411                 "backup_priv = %d\n",
3412                 dptr_num, mask, dirtype,
3413                 (long)fsp->dptr,
3414                 dptr_TellDir(fsp->dptr),
3415                 (int)backup_priv));
3416
3417         /* We don't need to check for VOL here as this is returned by
3418                 a different TRANS2 call. */
3419
3420         DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
3421                  directory,lp_dont_descend(ctx, lp_sub, SNUM(conn))));
3422         if (in_list(directory,lp_dont_descend(ctx, lp_sub, SNUM(conn)),conn->case_sensitive))
3423                 dont_descend = True;
3424
3425         p = pdata;
3426         space_remaining = max_data_bytes;
3427         out_of_space = False;
3428
3429         if (backup_priv) {
3430                 become_root();
3431                 as_root = true;
3432         }
3433
3434         /*
3435          * Seek to the correct position. We no longer use the resume key but
3436          * depend on the last file name instead.
3437          */
3438
3439         if(!continue_bit && resume_name && *resume_name) {
3440                 SMB_STRUCT_STAT st;
3441
3442                 long current_pos = 0;
3443                 /*
3444                  * Remember, name_to_8_3 is called by
3445                  * get_lanman2_dir_entry(), so the resume name
3446                  * could be mangled. Ensure we check the unmangled name.
3447                  */
3448
3449                 if (mangle_is_mangled(resume_name, conn->params)) {
3450                         char *new_resume_name = NULL;
3451                         mangle_lookup_name_from_8_3(ctx,
3452                                                 resume_name,
3453                                                 &new_resume_name,
3454                                                 conn->params);
3455                         if (new_resume_name) {
3456                                 resume_name = new_resume_name;
3457                         }
3458                 }
3459
3460                 /*
3461                  * Fix for NT redirector problem triggered by resume key indexes
3462                  * changing between directory scans. We now return a resume key of 0
3463                  * and instead look for the filename to continue from (also given
3464                  * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
3465                  * findfirst/findnext (as is usual) then the directory pointer
3466                  * should already be at the correct place.
3467                  */
3468
3469                 finished = !dptr_SearchDir(fsp->dptr, resume_name, &current_pos, &st);
3470         } /* end if resume_name && !continue_bit */
3471
3472         for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
3473                 bool got_exact_match = False;
3474
3475                 /* this is a heuristic to avoid seeking the fsp->dptr except when
3476                         absolutely necessary. It allows for a filename of about 40 chars */
3477                 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
3478                         out_of_space = True;
3479                         finished = False;
3480                 } else {
3481                         ntstatus = get_lanman2_dir_entry(ctx,
3482                                                 conn,
3483                                                 fsp->dptr,
3484                                                 req->flags2,
3485                                                 mask,dirtype,info_level,
3486                                                 requires_resume_key,dont_descend,
3487                                                 ask_sharemode,
3488                                                 &p,pdata,data_end,
3489                                                 space_remaining,
3490                                                 &got_exact_match,
3491                                                 &last_entry_off, ea_list);
3492                         if (NT_STATUS_EQUAL(ntstatus,
3493                                         NT_STATUS_ILLEGAL_CHARACTER)) {
3494                                 /*
3495                                  * Bad character conversion on name. Ignore this
3496                                  * entry.
3497                                  */
3498                                 continue;
3499                         }
3500                         if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
3501                                 out_of_space = true;
3502                         } else {
3503                                 finished = !NT_STATUS_IS_OK(ntstatus);
3504                         }
3505                 }
3506
3507                 if (!finished && !out_of_space)
3508                         numentries++;
3509
3510                 /*
3511                  * As an optimisation if we know we aren't looking
3512                  * for a wildcard name (ie. the name matches the wildcard exactly)
3513                  * then we can finish on any (first) match.
3514                  * This speeds up large directory searches. JRA.
3515                  */
3516
3517                 if(got_exact_match)
3518                         finished = True;
3519
3520                 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
3521         }
3522
3523         DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
3524                 smb_fn_name(req->cmd),
3525                 mask, directory, dirtype, numentries ) );
3526
3527         /* Check if we can close the fsp->dptr */
3528         if(close_after_request || (finished && close_if_end)) {
3529                 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
3530                 dptr_num = -1;
3531                 close_file(NULL, fsp, NORMAL_CLOSE);
3532                 fsp = NULL;
3533         }
3534
3535         if (as_root) {
3536                 unbecome_root();
3537         }
3538
3539         /* Set up the return parameter block */
3540         SSVAL(params,0,numentries);
3541         SSVAL(params,2,finished);
3542         SSVAL(params,4,0); /* Never an EA error */
3543         SSVAL(params,6,last_entry_off);
3544
3545         send_trans2_replies(conn, req, NT_STATUS_OK, params, 8, pdata, PTR_DIFF(p,pdata),
3546                             max_data_bytes);
3547
3548         return;
3549 }
3550
3551 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
3552 {
3553         const struct loadparm_substitution *lp_sub =
3554                 loadparm_s3_global_substitution();
3555
3556         E_md4hash(lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),objid);
3557         return objid;
3558 }
3559
3560 static void samba_extended_info_version(struct smb_extended_info *extended_info)
3561 {
3562         SMB_ASSERT(extended_info != NULL);
3563
3564         extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
3565         extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
3566                                        | ((SAMBA_VERSION_MINOR & 0xff) << 16)
3567                                        | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
3568 #ifdef SAMBA_VERSION_REVISION
3569         extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
3570 #endif
3571         extended_info->samba_subversion = 0;
3572 #ifdef SAMBA_VERSION_RC_RELEASE
3573         extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
3574 #else
3575 #ifdef SAMBA_VERSION_PRE_RELEASE
3576         extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
3577 #endif
3578 #endif
3579 #ifdef SAMBA_VERSION_VENDOR_PATCH
3580         extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
3581 #endif
3582         extended_info->samba_gitcommitdate = 0;
3583 #ifdef SAMBA_VERSION_COMMIT_TIME
3584         unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_COMMIT_TIME);
3585 #endif
3586
3587         memset(extended_info->samba_version_string, 0,
3588                sizeof(extended_info->samba_version_string));
3589
3590         snprintf (extended_info->samba_version_string,
3591                   sizeof(extended_info->samba_version_string),
3592                   "%s", samba_version_string());
3593 }
3594
3595 NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
3596                          connection_struct *conn,
3597                          TALLOC_CTX *mem_ctx,
3598                          uint16_t info_level,
3599                          uint16_t flags2,
3600                          unsigned int max_data_bytes,
3601                          size_t *fixed_portion,
3602                          struct smb_filename *fname,
3603                          char **ppdata,
3604                          int *ret_data_len)
3605 {
3606         const struct loadparm_substitution *lp_sub =
3607                 loadparm_s3_global_substitution();
3608         char *pdata, *end_data;
3609         int data_len = 0;
3610         size_t len = 0;
3611         const char *vname = volume_label(talloc_tos(), SNUM(conn));
3612         int snum = SNUM(conn);
3613         const char *fstype = lp_fstype(SNUM(conn));
3614         const char *filename = NULL;
3615         const uint64_t bytes_per_sector = 512;
3616         uint32_t additional_flags = 0;
3617         struct smb_filename smb_fname;
3618         SMB_STRUCT_STAT st;
3619         NTSTATUS status = NT_STATUS_OK;
3620         uint64_t df_ret;
3621
3622         if (fname == NULL || fname->base_name == NULL) {
3623                 filename = ".";
3624         } else {
3625                 filename = fname->base_name;
3626         }
3627
3628         if (IS_IPC(conn)) {
3629                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
3630                         DEBUG(0,("smbd_do_qfsinfo: not an allowed "
3631                                 "info level (0x%x) on IPC$.\n",
3632                                 (unsigned int)info_level));
3633                         return NT_STATUS_ACCESS_DENIED;
3634                 }
3635         }
3636
3637         DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
3638
3639         ZERO_STRUCT(smb_fname);
3640         smb_fname.base_name = discard_const_p(char, filename);
3641
3642         if(info_level != SMB_FS_QUOTA_INFORMATION
3643            && SMB_VFS_STAT(conn, &smb_fname) != 0) {
3644                 DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
3645                 return map_nt_error_from_unix(errno);
3646         }
3647
3648         st = smb_fname.st;
3649
3650         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
3651                 return NT_STATUS_INVALID_PARAMETER;
3652         }
3653
3654         *ppdata = (char *)SMB_REALLOC(
3655                 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
3656         if (*ppdata == NULL) {
3657                 return NT_STATUS_NO_MEMORY;
3658         }
3659
3660         pdata = *ppdata;
3661         memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
3662         end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
3663
3664         *fixed_portion = 0;
3665
3666         switch (info_level) {
3667                 case SMB_INFO_ALLOCATION:
3668                 {
3669                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
3670                         data_len = 18;
3671                         df_ret = get_dfree_info(conn, &smb_fname, &bsize,
3672                                                 &dfree, &dsize);
3673                         if (df_ret == (uint64_t)-1) {
3674                                 return map_nt_error_from_unix(errno);
3675                         }
3676
3677                         block_size = lp_block_size(snum);
3678                         if (bsize < block_size) {
3679                                 uint64_t factor = block_size/bsize;
3680                                 bsize = block_size;
3681                                 dsize /= factor;
3682                                 dfree /= factor;
3683                         }
3684                         if (bsize > block_size) {
3685                                 uint64_t factor = bsize/block_size;
3686                                 bsize = block_size;
3687                                 dsize *= factor;
3688                                 dfree *= factor;
3689                         }
3690                         sectors_per_unit = bsize/bytes_per_sector;
3691
3692                         DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
3693 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
3694                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
3695
3696                         /*
3697                          * For large drives, return max values and not modulo.
3698                          */
3699                         dsize = MIN(dsize, UINT32_MAX);
3700                         dfree = MIN(dfree, UINT32_MAX);
3701
3702                         SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
3703                         SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
3704                         SIVAL(pdata,l1_cUnit,dsize);
3705                         SIVAL(pdata,l1_cUnitAvail,dfree);
3706                         SSVAL(pdata,l1_cbSector,bytes_per_sector);
3707                         break;
3708                 }
3709
3710                 case SMB_INFO_VOLUME:
3711                         /* Return volume name */
3712                         /* 
3713                          * Add volume serial number - hash of a combination of
3714                          * the called hostname and the service name.
3715                          */
3716                         SIVAL(pdata,0,str_checksum(lp_servicename(talloc_tos(), lp_sub, snum)) ^ (str_checksum(get_local_machine_name())<<16) );
3717                         /*
3718                          * Win2k3 and previous mess this up by sending a name length
3719                          * one byte short. I believe only older clients (OS/2 Win9x) use
3720                          * this call so try fixing this by adding a terminating null to
3721                          * the pushed string. The change here was adding the STR_TERMINATE. JRA.
3722                          */
3723                         status = srvstr_push(
3724                                 pdata, flags2,
3725                                 pdata+l2_vol_szVolLabel, vname,
3726                                 PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
3727                                 STR_NOALIGN|STR_TERMINATE, &len);
3728                         if (!NT_STATUS_IS_OK(status)) {
3729                                 return status;
3730                         }
3731                         SCVAL(pdata,l2_vol_cch,len);
3732                         data_len = l2_vol_szVolLabel + len;
3733                         DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %u, name = %s\n",
3734                                  (unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
3735                                  (unsigned)len, vname));
3736                         break;
3737
3738                 case SMB_QUERY_FS_ATTRIBUTE_INFO:
3739                 case SMB_FS_ATTRIBUTE_INFORMATION:
3740
3741                         additional_flags = 0;
3742 #if defined(HAVE_SYS_QUOTAS)
3743                         additional_flags |= FILE_VOLUME_QUOTAS;
3744 #endif
3745
3746                         if(lp_nt_acl_support(SNUM(conn))) {
3747                                 additional_flags |= FILE_PERSISTENT_ACLS;
3748                         }
3749
3750                         /* Capabilities are filled in at connection time through STATVFS call */
3751                         additional_flags |= conn->fs_capabilities;
3752                         additional_flags |= lp_parm_int(conn->params->service,
3753                                                         "share", "fake_fscaps",
3754                                                         0);
3755
3756                         SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
3757                                 FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
3758                                 additional_flags); /* FS ATTRIBUTES */
3759
3760                         SIVAL(pdata,4,255); /* Max filename component length */
3761                         /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
3762                                 and will think we can't do long filenames */
3763                         status = srvstr_push(pdata, flags2, pdata+12, fstype,
3764                                           PTR_DIFF(end_data, pdata+12),
3765                                           STR_UNICODE, &len);
3766                         if (!NT_STATUS_IS_OK(status)) {
3767                                 return status;
3768                         }
3769                         SIVAL(pdata,8,len);
3770                         data_len = 12 + len;
3771                         if (max_data_bytes >= 16 && data_len > max_data_bytes) {
3772                                 /* the client only requested a portion of the
3773                                    file system name */
3774                                 data_len = max_data_bytes;
3775                                 status = STATUS_BUFFER_OVERFLOW;
3776                         }
3777                         *fixed_portion = 16;
3778                         break;
3779
3780                 case SMB_QUERY_FS_LABEL_INFO:
3781                 case SMB_FS_LABEL_INFORMATION:
3782                         status = srvstr_push(pdata, flags2, pdata+4, vname,
3783                                           PTR_DIFF(end_data, pdata+4), 0, &len);
3784                         if (!NT_STATUS_IS_OK(status)) {
3785                                 return status;
3786                         }
3787                         data_len = 4 + len;
3788                         SIVAL(pdata,0,len);
3789                         break;
3790
3791                 case SMB_QUERY_FS_VOLUME_INFO:      
3792                 case SMB_FS_VOLUME_INFORMATION:
3793
3794                         /* 
3795                          * Add volume serial number - hash of a combination of
3796                          * the called hostname and the service name.
3797                          */
3798                         SIVAL(pdata,8,str_checksum(lp_servicename(talloc_tos(), lp_sub, snum)) ^
3799                                 (str_checksum(get_local_machine_name())<<16));
3800
3801                         /* Max label len is 32 characters. */
3802                         status = srvstr_push(pdata, flags2, pdata+18, vname,
3803                                           PTR_DIFF(end_data, pdata+18),
3804                                           STR_UNICODE, &len);
3805                         if (!NT_STATUS_IS_OK(status)) {
3806                                 return status;
3807                         }
3808                         SIVAL(pdata,12,len);
3809                         data_len = 18+len;
3810
3811                         DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
3812                                 (int)strlen(vname),vname,
3813                                 lp_servicename(talloc_tos(), lp_sub, snum)));
3814                         if (max_data_bytes >= 24 && data_len > max_data_bytes) {
3815                                 /* the client only requested a portion of the
3816                                    volume label */
3817                                 data_len = max_data_bytes;
3818                                 status = STATUS_BUFFER_OVERFLOW;
3819                         }
3820                         *fixed_portion = 24;
3821                         break;
3822
3823                 case SMB_QUERY_FS_SIZE_INFO:
3824                 case SMB_FS_SIZE_INFORMATION:
3825                 {
3826                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
3827                         data_len = 24;
3828                         df_ret = get_dfree_info(conn, &smb_fname, &bsize,
3829                                                 &dfree, &dsize);
3830                         if (df_ret == (uint64_t)-1) {
3831                                 return map_nt_error_from_unix(errno);
3832                         }
3833                         block_size = lp_block_size(snum);
3834                         if (bsize < block_size) {
3835                                 uint64_t factor = block_size/bsize;
3836                                 bsize = block_size;
3837                                 dsize /= factor;
3838                                 dfree /= factor;
3839                         }
3840                         if (bsize > block_size) {
3841                                 uint64_t factor = bsize/block_size;
3842                                 bsize = block_size;
3843                                 dsize *= factor;
3844                                 dfree *= factor;
3845                         }
3846                         sectors_per_unit = bsize/bytes_per_sector;
3847                         DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3848 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
3849                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
3850                         SBIG_UINT(pdata,0,dsize);
3851                         SBIG_UINT(pdata,8,dfree);
3852                         SIVAL(pdata,16,sectors_per_unit);
3853                         SIVAL(pdata,20,bytes_per_sector);
3854                         *fixed_portion = 24;
3855                         break;
3856                 }
3857
3858                 case SMB_FS_FULL_SIZE_INFORMATION:
3859                 {
3860                         uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
3861                         data_len = 32;
3862                         df_ret = get_dfree_info(conn, &smb_fname, &bsize,
3863                                                 &dfree, &dsize);
3864                         if (df_ret == (uint64_t)-1) {
3865                                 return map_nt_error_from_unix(errno);
3866                         }
3867                         block_size = lp_block_size(snum);
3868                         if (bsize < block_size) {
3869                                 uint64_t factor = block_size/bsize;
3870                                 bsize = block_size;
3871                                 dsize /= factor;
3872                                 dfree /= factor;
3873                         }
3874                         if (bsize > block_size) {
3875                                 uint64_t factor = bsize/block_size;
3876                                 bsize = block_size;
3877                                 dsize *= factor;
3878                                 dfree *= factor;
3879                         }
3880                         sectors_per_unit = bsize/bytes_per_sector;
3881                         DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3882 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
3883                                 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
3884                         SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
3885                         SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
3886                         SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
3887                         SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
3888                         SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
3889                         *fixed_portion = 32;
3890                         break;
3891                 }
3892
3893                 case SMB_QUERY_FS_DEVICE_INFO:
3894                 case SMB_FS_DEVICE_INFORMATION:
3895                 {
3896                         uint32_t characteristics = FILE_DEVICE_IS_MOUNTED;
3897
3898                         if (!CAN_WRITE(conn)) {
3899                                 characteristics |= FILE_READ_ONLY_DEVICE;
3900                         }
3901                         data_len = 8;
3902                         SIVAL(pdata,0,FILE_DEVICE_DISK); /* dev type */
3903                         SIVAL(pdata,4,characteristics);
3904                         *fixed_portion = 8;
3905                         break;
3906                 }
3907
3908 #ifdef HAVE_SYS_QUOTAS
3909                 case SMB_FS_QUOTA_INFORMATION:
3910                 /* 
3911                  * what we have to send --metze:
3912                  *
3913                  * Unknown1:            24 NULL bytes
3914                  * Soft Quota Treshold: 8 bytes seems like uint64_t or so
3915                  * Hard Quota Limit:    8 bytes seems like uint64_t or so
3916                  * Quota Flags:         2 byte :
3917                  * Unknown3:            6 NULL bytes
3918                  *
3919                  * 48 bytes total
3920                  * 
3921                  * details for Quota Flags:
3922                  * 
3923                  * 0x0020 Log Limit: log if the user exceeds his Hard Quota
3924                  * 0x0010 Log Warn:  log if the user exceeds his Soft Quota
3925                  * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
3926                  * 0x0001 Enable Quotas: enable quota for this fs
3927                  *
3928                  */
3929                 {
3930                         /* we need to fake up a fsp here,
3931                          * because its not send in this call
3932                          */
3933                         files_struct fsp;
3934                         SMB_NTQUOTA_STRUCT quotas;
3935
3936                         ZERO_STRUCT(fsp);
3937                         ZERO_STRUCT(quotas);
3938
3939                         fsp.conn = conn;
3940                         fsp.fnum = FNUM_FIELD_INVALID;
3941
3942                         /* access check */
3943                         if (get_current_uid(conn) != 0) {
3944                                 DEBUG(0,("get_user_quota: access_denied "
3945                                          "service [%s] user [%s]\n",
3946                                          lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
3947                                          conn->session_info->unix_info->unix_name));
3948                                 return NT_STATUS_ACCESS_DENIED;
3949                         }
3950
3951                         status = vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE,
3952                                                  NULL, &quotas);
3953                         if (!NT_STATUS_IS_OK(status)) {
3954                                 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
3955                                 return status;
3956                         }
3957
3958                         data_len = 48;
3959
3960                         DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
3961                                   lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
3962
3963                         /* Unknown1 24 NULL bytes*/
3964                         SBIG_UINT(pdata,0,(uint64_t)0);
3965                         SBIG_UINT(pdata,8,(uint64_t)0);
3966                         SBIG_UINT(pdata,16,(uint64_t)0);
3967
3968                         /* Default Soft Quota 8 bytes */
3969                         SBIG_UINT(pdata,24,quotas.softlim);
3970
3971                         /* Default Hard Quota 8 bytes */
3972                         SBIG_UINT(pdata,32,quotas.hardlim);
3973
3974                         /* Quota flag 2 bytes */
3975                         SSVAL(pdata,40,quotas.qflags);
3976
3977                         /* Unknown3 6 NULL bytes */
3978                         SSVAL(pdata,42,0);
3979                         SIVAL(pdata,44,0);
3980
3981                         break;
3982                 }
3983 #endif /* HAVE_SYS_QUOTAS */
3984                 case SMB_FS_OBJECTID_INFORMATION:
3985                 {
3986                         unsigned char objid[16];
3987                         struct smb_extended_info extended_info;
3988                         memcpy(pdata,create_volume_objectid(conn, objid),16);
3989                         samba_extended_info_version (&extended_info);
3990                         SIVAL(pdata,16,extended_info.samba_magic);
3991                         SIVAL(pdata,20,extended_info.samba_version);
3992                         SIVAL(pdata,24,extended_info.samba_subversion);
3993                         SBIG_UINT(pdata,28,extended_info.samba_gitcommitdate);
3994                         memcpy(pdata+36,extended_info.samba_version_string,28);
3995                         data_len = 64;
3996                         break;
3997                 }
3998
3999                 case SMB_FS_SECTOR_SIZE_INFORMATION:
4000                 {
4001                         data_len = 28;
4002                         /*
4003                          * These values match a physical Windows Server 2012
4004                          * share backed by NTFS atop spinning rust.
4005                          */
4006                         DEBUG(5, ("SMB_FS_SECTOR_SIZE_INFORMATION:"));
4007                         /* logical_bytes_per_sector */
4008                         SIVAL(pdata, 0, bytes_per_sector);
4009                         /* phys_bytes_per_sector_atomic */
4010                         SIVAL(pdata, 4, bytes_per_sector);
4011                         /* phys_bytes_per_sector_perf */
4012                         SIVAL(pdata, 8, bytes_per_sector);
4013                         /* fs_effective_phys_bytes_per_sector_atomic */
4014                         SIVAL(pdata, 12, bytes_per_sector);
4015                         /* flags */
4016                         SIVAL(pdata, 16, SSINFO_FLAGS_ALIGNED_DEVICE
4017                                 | SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE);
4018                         /* byte_off_sector_align */
4019                         SIVAL(pdata, 20, 0);
4020                         /* byte_off_partition_align */
4021                         SIVAL(pdata, 24, 0);
4022                         *fixed_portion = 28;
4023                         break;
4024                 }
4025
4026
4027                 /*
4028                  * Query the version and capabilities of the CIFS UNIX extensions
4029                  * in use.
4030                  */
4031
4032                 case SMB_QUERY_CIFS_UNIX_INFO:
4033                 {
4034                         bool large_write = lp_min_receive_file_size() &&
4035                                         !srv_is_signing_active(xconn);
4036                         bool large_read = !srv_is_signing_active(xconn);
4037                         int encrypt_caps = 0;
4038
4039                         if (!lp_unix_extensions()) {
4040                                 return NT_STATUS_INVALID_LEVEL;
4041                         }
4042
4043                         switch (conn->encrypt_level) {
4044                         case SMB_SIGNING_OFF:
4045                                 encrypt_caps = 0;
4046                                 break;
4047                         case SMB_SIGNING_DESIRED:
4048                         case SMB_SIGNING_IF_REQUIRED:
4049                         case SMB_SIGNING_DEFAULT:
4050                                 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP;
4051                                 break;
4052                         case SMB_SIGNING_REQUIRED:
4053                                 encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP|
4054                                                 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP;
4055                                 large_write = false;
4056                                 large_read = false;
4057                                 break;
4058                         }
4059
4060                         data_len = 12;
4061                         SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
4062                         SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
4063
4064                         /* We have POSIX ACLs, pathname, encryption, 
4065                          * large read/write, and locking capability. */
4066
4067                         SBIG_UINT(pdata,4,((uint64_t)(
4068                                         CIFS_UNIX_POSIX_ACLS_CAP|
4069                                         CIFS_UNIX_POSIX_PATHNAMES_CAP|
4070                                         CIFS_UNIX_FCNTL_LOCKS_CAP|
4071                                         CIFS_UNIX_EXTATTR_CAP|
4072                                         CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP|
4073                                         encrypt_caps|
4074                                         (large_read ? CIFS_UNIX_LARGE_READ_CAP : 0) |
4075                                         (large_write ?
4076                                         CIFS_UNIX_LARGE_WRITE_CAP : 0))));
4077                         break;
4078                 }
4079
4080                 case SMB_QUERY_POSIX_FS_INFO:
4081                 {
4082                         int rc;
4083                         vfs_statvfs_struct svfs;
4084
4085                         if (!lp_unix_extensions()) {
4086                                 return NT_STATUS_INVALID_LEVEL;
4087                         }
4088
4089                         rc = SMB_VFS_STATVFS(conn, &smb_fname, &svfs);
4090
4091                         if (!rc) {
4092                                 data_len = 56;
4093                                 SIVAL(pdata,0,svfs.OptimalTransferSize);
4094                                 SIVAL(pdata,4,svfs.BlockSize);
4095                                 SBIG_UINT(pdata,8,svfs.TotalBlocks);
4096                                 SBIG_UINT(pdata,16,svfs.BlocksAvail);
4097                                 SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
4098                                 SBIG_UINT(pdata,32,svfs.TotalFileNodes);
4099                                 SBIG_UINT(pdata,40,svfs.FreeFileNodes);
4100                                 SBIG_UINT(pdata,48,svfs.FsIdentifier);
4101                                 DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
4102 #ifdef EOPNOTSUPP
4103                         } else if (rc == EOPNOTSUPP) {
4104                                 return NT_STATUS_INVALID_LEVEL;
4105 #endif /* EOPNOTSUPP */
4106                         } else {
4107                                 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4108                                 return NT_STATUS_DOS(ERRSRV, ERRerror);
4109                         }
4110                         break;
4111                 }
4112
4113                 case SMB_QUERY_POSIX_WHOAMI:
4114                 {
4115                         uint32_t flags = 0;
4116                         uint32_t sid_bytes;
4117                         int i;
4118
4119                         if (!lp_unix_extensions()) {
4120                                 return NT_STATUS_INVALID_LEVEL;
4121                         }
4122
4123                         if (max_data_bytes < 40) {
4124                                 return NT_STATUS_BUFFER_TOO_SMALL;
4125                         }
4126
4127                         if (security_session_user_level(conn->session_info, NULL) < SECURITY_USER) {
4128                                 flags |= SMB_WHOAMI_GUEST;
4129                         }
4130
4131                         /* NOTE: 8 bytes for UID/GID, irrespective of native
4132                          * platform size. This matches
4133                          * SMB_QUERY_FILE_UNIX_BASIC and friends.
4134                          */
4135                         data_len = 4 /* flags */
4136                             + 4 /* flag mask */
4137                             + 8 /* uid */
4138                             + 8 /* gid */
4139                             + 4 /* ngroups */
4140                             + 4 /* num_sids */
4141                             + 4 /* SID bytes */
4142                             + 4 /* pad/reserved */
4143                             + (conn->session_info->unix_token->ngroups * 8)
4144                                 /* groups list */
4145                             + (conn->session_info->security_token->num_sids *
4146                                     SID_MAX_SIZE)
4147                                 /* SID list */;
4148
4149                         SIVAL(pdata, 0, flags);
4150                         SIVAL(pdata, 4, SMB_WHOAMI_MASK);
4151                         SBIG_UINT(pdata, 8,
4152                                   (uint64_t)conn->session_info->unix_token->uid);
4153                         SBIG_UINT(pdata, 16,
4154                                   (uint64_t)conn->session_info->unix_token->gid);
4155
4156
4157                         if (data_len >= max_data_bytes) {
4158                                 /* Potential overflow, skip the GIDs and SIDs. */
4159
4160                                 SIVAL(pdata, 24, 0); /* num_groups */
4161                                 SIVAL(pdata, 28, 0); /* num_sids */
4162                                 SIVAL(pdata, 32, 0); /* num_sid_bytes */
4163                                 SIVAL(pdata, 36, 0); /* reserved */
4164
4165                                 data_len = 40;
4166                                 break;
4167                         }
4168
4169                         SIVAL(pdata, 24, conn->session_info->unix_token->ngroups);
4170                         SIVAL(pdata, 28, conn->session_info->security_token->num_sids);
4171
4172                         /* We walk the SID list twice, but this call is fairly
4173                          * infrequent, and I don't expect that it's performance
4174                          * sensitive -- jpeach
4175                          */
4176                         for (i = 0, sid_bytes = 0;
4177                              i < conn->session_info->security_token->num_sids; ++i) {
4178                                 sid_bytes += ndr_size_dom_sid(
4179                                         &conn->session_info->security_token->sids[i],
4180                                         0);
4181                         }
4182
4183                         /* SID list byte count */
4184                         SIVAL(pdata, 32, sid_bytes);
4185
4186                         /* 4 bytes pad/reserved - must be zero */
4187                         SIVAL(pdata, 36, 0);
4188                         data_len = 40;
4189
4190                         /* GID list */
4191                         for (i = 0; i < conn->session_info->unix_token->ngroups; ++i) {
4192                                 SBIG_UINT(pdata, data_len,
4193                                           (uint64_t)conn->session_info->unix_token->groups[i]);
4194                                 data_len += 8;
4195                         }
4196
4197                         /* SID list */
4198                         for (i = 0;
4199                             i < conn->session_info->security_token->num_sids; ++i) {
4200                                 int sid_len = ndr_size_dom_sid(
4201                                         &conn->session_info->security_token->sids[i],
4202                                         0);
4203
4204                                 sid_linearize((uint8_t *)(pdata + data_len),
4205                                               sid_len,
4206                                     &conn->session_info->security_token->sids[i]);
4207                                 data_len += sid_len;
4208                         }
4209
4210                         break;
4211                 }
4212
4213                 case SMB_MAC_QUERY_FS_INFO:
4214                         /*
4215                          * Thursby MAC extension... ONLY on NTFS filesystems
4216                          * once we do streams then we don't need this
4217                          */
4218                         if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
4219                                 data_len = 88;
4220                                 SIVAL(pdata,84,0x100); /* Don't support mac... */
4221                                 break;
4222                         }
4223
4224                         FALL_THROUGH;
4225                 default:
4226                         return NT_STATUS_INVALID_LEVEL;
4227         }
4228
4229         *ret_data_len = data_len;
4230         return status;
4231 }
4232
4233 static NTSTATUS smb_set_fsquota(connection_struct *conn,
4234                         struct smb_request *req,
4235                         files_struct *fsp,
4236                         const DATA_BLOB *qdata)
4237 {
4238         const struct loadparm_substitution *lp_sub =
4239                 loadparm_s3_global_substitution();
4240         NTSTATUS status;
4241         SMB_NTQUOTA_STRUCT quotas;
4242
4243         ZERO_STRUCT(quotas);
4244
4245         /* access check */
4246         if ((get_current_uid(conn) != 0) || !CAN_WRITE(conn)) {
4247                 DEBUG(3, ("set_fsquota: access_denied service [%s] user [%s]\n",
4248                           lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
4249                           conn->session_info->unix_info->unix_name));
4250                 return NT_STATUS_ACCESS_DENIED;
4251         }
4252
4253         if (!check_fsp_ntquota_handle(conn, req,
4254                                       fsp)) {
4255                 DEBUG(1, ("set_fsquota: no valid QUOTA HANDLE\n"));
4256                 return NT_STATUS_INVALID_HANDLE;
4257         }
4258
4259         /* note: normally there're 48 bytes,
4260          * but we didn't use the last 6 bytes for now
4261          * --metze
4262          */
4263         if (qdata->length < 42) {
4264                 DEBUG(0,("set_fsquota: requires total_data(%u) >= 42 bytes!\n",
4265                         (unsigned int)qdata->length));
4266                 return NT_STATUS_INVALID_PARAMETER;
4267         }
4268
4269         /* unknown_1 24 NULL bytes in pdata*/
4270
4271         /* the soft quotas 8 bytes (uint64_t)*/
4272         quotas.softlim = BVAL(qdata->data,24);
4273
4274         /* the hard quotas 8 bytes (uint64_t)*/
4275         quotas.hardlim = BVAL(qdata->data,32);
4276
4277         /* quota_flags 2 bytes **/
4278         quotas.qflags = SVAL(qdata->data,40);
4279
4280         /* unknown_2 6 NULL bytes follow*/
4281
4282         /* now set the quotas */
4283         if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
4284                 DEBUG(1, ("vfs_set_ntquota() failed for service [%s]\n",
4285                           lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4286                 status =  map_nt_error_from_unix(errno);
4287         } else {
4288                 status = NT_STATUS_OK;
4289         }
4290         return status;
4291 }
4292
4293 NTSTATUS smbd_do_setfsinfo(connection_struct *conn,
4294                                 struct smb_request *req,
4295                                 TALLOC_CTX *mem_ctx,
4296                                 uint16_t info_level,
4297                                 files_struct *fsp,
4298                                 const DATA_BLOB *pdata)
4299 {
4300         switch (info_level) {
4301                 case SMB_FS_QUOTA_INFORMATION:
4302                 {
4303                         return smb_set_fsquota(conn,
4304                                                 req,
4305                                                 fsp,
4306                                                 pdata);
4307                 }
4308
4309                 default:
4310                         break;
4311         }
4312         return NT_STATUS_INVALID_LEVEL;
4313 }
4314
4315 /****************************************************************************
4316  Reply to a TRANS2_QFSINFO (query filesystem info).
4317 ****************************************************************************/
4318
4319 static void call_trans2qfsinfo(connection_struct *conn,
4320                                struct smb_request *req,
4321                                char **pparams, int total_params,
4322                                char **ppdata, int total_data,
4323                                unsigned int max_data_bytes)
4324 {
4325         char *params = *pparams;
4326         uint16_t info_level;
4327         int data_len = 0;
4328         size_t fixed_portion;
4329         NTSTATUS status;
4330
4331         if (total_params < 2) {
4332                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4333                 return;
4334         }
4335
4336         info_level = SVAL(params,0);
4337
4338         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
4339                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
4340                         DEBUG(0,("call_trans2qfsinfo: encryption required "
4341                                 "and info level 0x%x sent.\n",
4342                                 (unsigned int)info_level));
4343                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4344                         return;
4345                 }
4346         }
4347
4348         DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
4349
4350         status = smbd_do_qfsinfo(req->xconn, conn, req,
4351                                  info_level,
4352                                  req->flags2,
4353                                  max_data_bytes,
4354                                  &fixed_portion,
4355                                  NULL,
4356                                  ppdata, &data_len);
4357         if (!NT_STATUS_IS_OK(status)) {
4358                 reply_nterror(req, status);
4359                 return;
4360         }
4361
4362         send_trans2_replies(conn, req, NT_STATUS_OK, params, 0, *ppdata, data_len,
4363                             max_data_bytes);
4364
4365         DEBUG( 4, ( "%s info_level = %d\n",
4366                     smb_fn_name(req->cmd), info_level) );
4367
4368         return;
4369 }
4370
4371 /****************************************************************************
4372  Reply to a TRANS2_SETFSINFO (set filesystem info).
4373 ****************************************************************************/
4374
4375 static void call_trans2setfsinfo(connection_struct *conn,
4376                                  struct smb_request *req,
4377                                  char **pparams, int total_params,
4378                                  char **ppdata, int total_data,
4379                                  unsigned int max_data_bytes)
4380 {
4381         const struct loadparm_substitution *lp_sub =
4382                 loadparm_s3_global_substitution();
4383         struct smbXsrv_connection *xconn = req->xconn;
4384         char *pdata = *ppdata;
4385         char *params = *pparams;
4386         uint16_t info_level;
4387
4388         DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",
4389                   lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4390
4391         /*  */
4392         if (total_params < 4) {
4393                 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
4394                         total_params));
4395                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4396                 return;
4397         }
4398
4399         info_level = SVAL(params,2);
4400
4401         if (IS_IPC(conn)) {
4402                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION &&
4403                                 info_level != SMB_SET_CIFS_UNIX_INFO) {
4404                         DEBUG(0,("call_trans2setfsinfo: not an allowed "
4405                                 "info level (0x%x) on IPC$.\n",
4406                                 (unsigned int)info_level));
4407                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4408                         return;
4409                 }
4410         }
4411
4412         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
4413                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
4414                         DEBUG(0,("call_trans2setfsinfo: encryption required "
4415                                 "and info level 0x%x sent.\n",
4416                                 (unsigned int)info_level));
4417                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4418                         return;
4419                 }
4420         }
4421
4422         switch(info_level) {
4423                 case SMB_SET_CIFS_UNIX_INFO:
4424                         if (!lp_unix_extensions()) {
4425                                 DEBUG(2,("call_trans2setfsinfo: "
4426                                         "SMB_SET_CIFS_UNIX_INFO is invalid with "
4427                                         "unix extensions off\n"));
4428                                 reply_nterror(req,
4429                                               NT_STATUS_INVALID_LEVEL);
4430                                 return;
4431                         }
4432
4433                         /* There should be 12 bytes of capabilities set. */
4434                         if (total_data < 12) {
4435                                 reply_nterror(
4436                                         req,
4437                                         NT_STATUS_INVALID_PARAMETER);
4438                                 return;
4439                         }
4440                         xconn->smb1.unix_info.client_major = SVAL(pdata,0);
4441                         xconn->smb1.unix_info.client_minor = SVAL(pdata,2);
4442                         xconn->smb1.unix_info.client_cap_low = IVAL(pdata,4);
4443                         xconn->smb1.unix_info.client_cap_high = IVAL(pdata,8);
4444                         /* Just print these values for now. */
4445                         DEBUG(10, ("call_trans2setfsinfo: set unix_info info. "
4446                                    "major = %u, minor = %u cap_low = 0x%x, "
4447                                    "cap_high = 0x%xn",
4448                                    (unsigned int)xconn->
4449                                    smb1.unix_info.client_major,
4450                                    (unsigned int)xconn->
4451                                    smb1.unix_info.client_minor,
4452                                    (unsigned int)xconn->
4453                                    smb1.unix_info.client_cap_low,
4454                                    (unsigned int)xconn->
4455                                    smb1.unix_info.client_cap_high));
4456
4457                         /* Here is where we must switch to posix pathname processing... */
4458                         if (xconn->smb1.unix_info.client_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
4459                                 lp_set_posix_pathnames();
4460                                 mangle_change_to_posix();
4461                         }
4462
4463                         if ((xconn->smb1.unix_info.client_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
4464                             !(xconn->smb1.unix_info.client_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
4465                                 /* Client that knows how to do posix locks,
4466                                  * but not posix open/mkdir operations. Set a
4467                                  * default type for read/write checks. */
4468
4469                                 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
4470
4471                         }
4472                         break;
4473
4474                 case SMB_REQUEST_TRANSPORT_ENCRYPTION:
4475                         {
4476                                 NTSTATUS status;
4477                                 size_t param_len = 0;
4478                                 size_t data_len = total_data;
4479
4480                                 if (!lp_unix_extensions()) {
4481                                         reply_nterror(
4482                                                 req,
4483                                                 NT_STATUS_INVALID_LEVEL);
4484                                         return;
4485                                 }
4486
4487                                 if (lp_smb_encrypt(SNUM(conn)) == SMB_SIGNING_OFF) {
4488                                         reply_nterror(
4489                                                 req,
4490                                                 NT_STATUS_NOT_SUPPORTED);
4491                                         return;
4492                                 }
4493
4494                                 if (xconn->smb1.echo_handler.trusted_fde) {
4495                                         DEBUG( 2,("call_trans2setfsinfo: "
4496                                                 "request transport encryption disabled"
4497                                                 "with 'fork echo handler = yes'\n"));
4498                                         reply_nterror(
4499                                                 req,
4500                                                 NT_STATUS_NOT_SUPPORTED);
4501                                         return;
4502                                 }
4503
4504                                 DEBUG( 4,("call_trans2setfsinfo: "
4505                                         "request transport encryption.\n"));
4506
4507                                 status = srv_request_encryption_setup(conn,
4508                                                                 (unsigned char **)ppdata,
4509                                                                 &data_len,
4510                                                                 (unsigned char **)pparams,
4511                                                                 &param_len);
4512
4513                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
4514                                                 !NT_STATUS_IS_OK(status)) {
4515                                         reply_nterror(req, status);
4516                                         return;
4517                                 }
4518
4519                                 send_trans2_replies(conn, req,
4520                                                 NT_STATUS_OK,
4521                                                 *pparams,
4522                                                 param_len,
4523                                                 *ppdata,
4524                                                 data_len,
4525                                                 max_data_bytes);
4526
4527                                 if (NT_STATUS_IS_OK(status)) {
4528                                         /* Server-side transport
4529                                          * encryption is now *on*. */
4530                                         status = srv_encryption_start(conn);
4531                                         if (!NT_STATUS_IS_OK(status)) {
4532                                                 char *reason = talloc_asprintf(talloc_tos(),
4533                                                                                "Failure in setting "
4534                                                                                "up encrypted transport: %s",
4535                                                                                nt_errstr(status));
4536                                                 exit_server_cleanly(reason);
4537                                         }
4538                                 }
4539                                 return;
4540                         }
4541
4542                 case SMB_FS_QUOTA_INFORMATION:
4543                         {
4544                                 NTSTATUS status;
4545                                 DATA_BLOB qdata = {
4546                                                 .data = (uint8_t *)pdata,
4547                                                 .length = total_data
4548                                 };
4549                                 files_struct *fsp = NULL;
4550                                 fsp = file_fsp(req, SVAL(params,0));
4551
4552                                 status = smb_set_fsquota(conn,
4553                                                         req,
4554                                                         fsp,
4555                                                         &qdata);
4556                                 if (!NT_STATUS_IS_OK(status)) {
4557                                         reply_nterror(req, status);
4558                                         return;
4559                                 }
4560                                 break;
4561                         }
4562                 default:
4563                         DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
4564                                 info_level));
4565                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
4566                         return;
4567                         break;
4568         }
4569
4570         /* 
4571          * sending this reply works fine, 
4572          * but I'm not sure it's the same 
4573          * like windows do...
4574          * --metze
4575          */
4576         reply_outbuf(req, 10, 0);
4577 }
4578
4579 #if defined(HAVE_POSIX_ACLS)
4580 /****************************************************************************
4581  Utility function to count the number of entries in a POSIX acl.
4582 ****************************************************************************/
4583
4584 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
4585 {
4586         unsigned int ace_count = 0;
4587         int entry_id = SMB_ACL_FIRST_ENTRY;
4588         SMB_ACL_ENTRY_T entry;
4589
4590         while ( posix_acl && (sys_acl_get_entry(posix_acl, entry_id, &entry) == 1)) {
4591                 /* get_next... */
4592                 if (entry_id == SMB_ACL_FIRST_ENTRY) {
4593                         entry_id = SMB_ACL_NEXT_ENTRY;
4594                 }
4595                 ace_count++;
4596         }
4597         return ace_count;
4598 }
4599
4600 /****************************************************************************
4601  Utility function to marshall a POSIX acl into wire format.
4602 ****************************************************************************/
4603
4604 static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
4605 {
4606         int entry_id = SMB_ACL_FIRST_ENTRY;
4607         SMB_ACL_ENTRY_T entry;
4608
4609         while ( posix_acl && (sys_acl_get_entry(posix_acl, entry_id, &entry) == 1)) {
4610                 SMB_ACL_TAG_T tagtype;
4611                 SMB_ACL_PERMSET_T permset;
4612                 unsigned char perms = 0;
4613                 unsigned int own_grp;
4614
4615                 /* get_next... */
4616                 if (entry_id == SMB_ACL_FIRST_ENTRY) {
4617                         entry_id = SMB_ACL_NEXT_ENTRY;
4618                 }
4619
4620                 if (sys_acl_get_tag_type(entry, &tagtype) == -1) {
4621                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
4622                         return False;
4623                 }
4624
4625                 if (sys_acl_get_permset(entry, &permset) == -1) {
4626                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
4627                         return False;
4628                 }
4629
4630                 perms |= (sys_acl_get_perm(permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
4631                 perms |= (sys_acl_get_perm(permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
4632                 perms |= (sys_acl_get_perm(permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
4633
4634                 SCVAL(pdata,1,perms);
4635
4636                 switch (tagtype) {
4637                         case SMB_ACL_USER_OBJ:
4638                                 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
4639                                 own_grp = (unsigned int)pst->st_ex_uid;
4640                                 SIVAL(pdata,2,own_grp);
4641                                 SIVAL(pdata,6,0);
4642                                 break;
4643                         case SMB_ACL_USER:
4644                                 {
4645                                         uid_t *puid = (uid_t *)sys_acl_get_qualifier(entry);
4646                                         if (!puid) {
4647                                                 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
4648                                                 return False;
4649                                         }
4650                                         own_grp = (unsigned int)*puid;
4651                                         SCVAL(pdata,0,SMB_POSIX_ACL_USER);
4652                                         SIVAL(pdata,2,own_grp);
4653                                         SIVAL(pdata,6,0);
4654                                         break;
4655                                 }
4656                         case SMB_ACL_GROUP_OBJ:
4657                                 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
4658                                 own_grp = (unsigned int)pst->st_ex_gid;
4659                                 SIVAL(pdata,2,own_grp);
4660                                 SIVAL(pdata,6,0);
4661                                 break;
4662                         case SMB_ACL_GROUP:
4663                                 {
4664                                         gid_t *pgid= (gid_t *)sys_acl_get_qualifier(entry);
4665                                         if (!pgid) {
4666                                                 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
4667                                                 return False;
4668                                         }
4669                                         own_grp = (unsigned int)*pgid;
4670                                         SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
4671                                         SIVAL(pdata,2,own_grp);
4672                                         SIVAL(pdata,6,0);
4673                                         break;
4674                                 }
4675                         case SMB_ACL_MASK:
4676                                 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
4677                                 SIVAL(pdata,2,0xFFFFFFFF);
4678                                 SIVAL(pdata,6,0xFFFFFFFF);
4679                                 break;
4680                         case SMB_ACL_OTHER:
4681                                 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
4682                                 SIVAL(pdata,2,0xFFFFFFFF);
4683                                 SIVAL(pdata,6,0xFFFFFFFF);
4684                                 break;
4685                         default:
4686                                 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
4687                                 return False;
4688                 }
4689                 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
4690         }
4691
4692         return True;
4693 }
4694 #endif
4695
4696 /****************************************************************************
4697  Store the FILE_UNIX_BASIC info.
4698 ****************************************************************************/
4699
4700 static char *store_file_unix_basic(connection_struct *conn,
4701                                 char *pdata,
4702                                 files_struct *fsp,
4703                                 const SMB_STRUCT_STAT *psbuf)
4704 {
4705         dev_t devno;
4706
4707         DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
4708         DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_ex_mode));
4709
4710         SOFF_T(pdata,0,get_file_size_stat(psbuf));             /* File size 64 Bit */
4711         pdata += 8;
4712
4713         SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
4714         pdata += 8;
4715
4716         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata, &psbuf->st_ex_ctime);       /* Change Time 64 Bit */
4717         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER ,pdata+8, &psbuf->st_ex_atime);     /* Last access time 64 Bit */
4718         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata+16, &psbuf->st_ex_mtime);    /* Last modification time 64 Bit */
4719         pdata += 24;
4720
4721         SIVAL(pdata,0,psbuf->st_ex_uid);               /* user id for the owner */
4722         SIVAL(pdata,4,0);
4723         pdata += 8;
4724
4725         SIVAL(pdata,0,psbuf->st_ex_gid);               /* group id of owner */
4726         SIVAL(pdata,4,0);
4727         pdata += 8;
4728
4729         SIVAL(pdata,0,unix_filetype(psbuf->st_ex_mode));
4730         pdata += 4;
4731
4732         if (S_ISBLK(psbuf->st_ex_mode) || S_ISCHR(psbuf->st_ex_mode)) {
4733                 devno = psbuf->st_ex_rdev;
4734         } else {
4735                 devno = psbuf->st_ex_dev;
4736         }
4737
4738         SIVAL(pdata,0,unix_dev_major(devno));   /* Major device number if type is device */
4739         SIVAL(pdata,4,0);
4740         pdata += 8;
4741
4742         SIVAL(pdata,0,unix_dev_minor(devno));   /* Minor device number if type is device */
4743         SIVAL(pdata,4,0);
4744         pdata += 8;
4745
4746         SINO_T_VAL(pdata, 0, psbuf->st_ex_ino);   /* inode number */
4747         pdata += 8;
4748
4749         SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode));     /* Standard UNIX file permissions */
4750         SIVAL(pdata,4,0);
4751         pdata += 8;
4752
4753         SIVAL(pdata,0,psbuf->st_ex_nlink);             /* number of hard links */
4754         SIVAL(pdata,4,0);
4755         pdata += 8;
4756
4757         return pdata;
4758 }
4759
4760 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
4761  * the chflags(2) (or equivalent) flags.
4762  *
4763  * XXX: this really should be behind the VFS interface. To do this, we would
4764  * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
4765  * Each VFS module could then implement its own mapping as appropriate for the
4766  * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
4767  */
4768 static const struct {unsigned stat_fflag; unsigned smb_fflag;}
4769         info2_flags_map[] =
4770 {
4771 #ifdef UF_NODUMP
4772     { UF_NODUMP, EXT_DO_NOT_BACKUP },
4773 #endif
4774
4775 #ifdef UF_IMMUTABLE
4776     { UF_IMMUTABLE, EXT_IMMUTABLE },
4777 #endif
4778
4779 #ifdef UF_APPEND
4780     { UF_APPEND, EXT_OPEN_APPEND_ONLY },
4781 #endif
4782
4783 #ifdef UF_HIDDEN
4784     { UF_HIDDEN, EXT_HIDDEN },
4785 #endif
4786
4787     /* Do not remove. We need to guarantee that this array has at least one
4788      * entry to build on HP-UX.
4789      */
4790     { 0, 0 }
4791
4792 };
4793
4794 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf,
4795                                 uint32_t *smb_fflags, uint32_t *smb_fmask)
4796 {
4797         int i;
4798
4799         for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
4800             *smb_fmask |= info2_flags_map[i].smb_fflag;
4801             if (psbuf->st_ex_flags & info2_flags_map[i].stat_fflag) {
4802                     *smb_fflags |= info2_flags_map[i].smb_fflag;
4803             }
4804         }
4805 }
4806
4807 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
4808                                 const uint32_t smb_fflags,
4809                                 const uint32_t smb_fmask,
4810                                 int *stat_fflags)
4811 {
4812         uint32_t max_fmask = 0;
4813         int i;
4814
4815         *stat_fflags = psbuf->st_ex_flags;
4816
4817         /* For each flags requested in smb_fmask, check the state of the
4818          * corresponding flag in smb_fflags and set or clear the matching
4819          * stat flag.
4820          */
4821
4822         for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
4823             max_fmask |= info2_flags_map[i].smb_fflag;
4824             if (smb_fmask & info2_flags_map[i].smb_fflag) {
4825                     if (smb_fflags & info2_flags_map[i].smb_fflag) {
4826                             *stat_fflags |= info2_flags_map[i].stat_fflag;
4827                     } else {
4828                             *stat_fflags &= ~info2_flags_map[i].stat_fflag;
4829                     }
4830             }
4831         }
4832
4833         /* If smb_fmask is asking to set any bits that are not supported by
4834          * our flag mappings, we should fail.
4835          */
4836         if ((smb_fmask & max_fmask) != smb_fmask) {
4837                 return False;
4838         }
4839
4840         return True;
4841 }
4842
4843
4844 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
4845  * of file flags and birth (create) time.
4846  */
4847 static char *store_file_unix_basic_info2(connection_struct *conn,
4848                                 char *pdata,
4849                                 files_struct *fsp,
4850                                 const SMB_STRUCT_STAT *psbuf)
4851 {
4852         uint32_t file_flags = 0;
4853         uint32_t flags_mask = 0;
4854
4855         pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
4856
4857         /* Create (birth) time 64 bit */
4858         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER,pdata, &psbuf->st_ex_btime);
4859         pdata += 8;
4860
4861         map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
4862         SIVAL(pdata, 0, file_flags); /* flags */
4863         SIVAL(pdata, 4, flags_mask); /* mask */
4864         pdata += 8;
4865
4866         return pdata;
4867 }
4868
4869 static NTSTATUS marshall_stream_info(unsigned int num_streams,
4870                                      const struct stream_struct *streams,
4871                                      char *data,
4872                                      unsigned int max_data_bytes,
4873                                      unsigned int *data_size)
4874 {
4875         unsigned int i;
4876         unsigned int ofs = 0;
4877
4878         if (max_data_bytes < 32) {
4879                 return NT_STATUS_INFO_LENGTH_MISMATCH;
4880         }
4881
4882         for (i = 0; i < num_streams; i++) {
4883                 unsigned int next_offset;
4884                 size_t namelen;
4885                 smb_ucs2_t *namebuf;
4886
4887                 if (!push_ucs2_talloc(talloc_tos(), &namebuf,
4888                                       streams[i].name, &namelen) ||
4889                     namelen <= 2)
4890                 {
4891                         return NT_STATUS_INVALID_PARAMETER;
4892                 }
4893
4894                 /*
4895                  * name_buf is now null-terminated, we need to marshall as not
4896                  * terminated
4897                  */
4898
4899                 namelen -= 2;
4900
4901                 /*
4902                  * We cannot overflow ...
4903                  */
4904                 if ((ofs + 24 + namelen) > max_data_bytes) {
4905                         DEBUG(10, ("refusing to overflow reply at stream %u\n",
4906                                 i));
4907                         TALLOC_FREE(namebuf);
4908                         return STATUS_BUFFER_OVERFLOW;
4909                 }
4910
4911                 SIVAL(data, ofs+4, namelen);
4912                 SOFF_T(data, ofs+8, streams[i].size);
4913                 SOFF_T(data, ofs+16, streams[i].alloc_size);
4914                 memcpy(data+ofs+24, namebuf, namelen);
4915                 TALLOC_FREE(namebuf);
4916
4917                 next_offset = ofs + 24 + namelen;
4918
4919                 if (i == num_streams-1) {
4920                         SIVAL(data, ofs, 0);
4921                 }
4922                 else {
4923                         unsigned int align = ndr_align_size(next_offset, 8);
4924
4925                         if ((next_offset + align) > max_data_bytes) {
4926                                 DEBUG(10, ("refusing to overflow align "
4927                                         "reply at stream %u\n",
4928                                         i));
4929                                 TALLOC_FREE(namebuf);
4930                                 return STATUS_BUFFER_OVERFLOW;
4931                         }
4932
4933                         memset(data+next_offset, 0, align);
4934                         next_offset += align;
4935
4936                         SIVAL(data, ofs, next_offset - ofs);
4937                         ofs = next_offset;
4938                 }
4939
4940                 ofs = next_offset;
4941         }
4942
4943         DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes, ofs));
4944
4945         *data_size = ofs;
4946
4947         return NT_STATUS_OK;
4948 }
4949
4950 #if defined(HAVE_POSIX_ACLS)
4951 static NTSTATUS smb_query_posix_acl(connection_struct *conn,
4952                                 struct smb_request *req,
4953                                 files_struct *fsp,
4954                                 struct smb_filename *smb_fname,
4955                                 char *pdata,
4956                                 unsigned int data_size_in,
4957                                 unsigned int *pdata_size_out)
4958 {
4959         SMB_ACL_T file_acl = NULL;
4960         SMB_ACL_T def_acl = NULL;
4961         uint16_t num_file_acls = 0;
4962         uint16_t num_def_acls = 0;
4963         unsigned int size_needed = 0;
4964         NTSTATUS status;
4965         bool ok;
4966         bool close_fsp = false;
4967
4968         /*
4969          * Ensure we always operate on a file descriptor, not just
4970          * the filename.
4971          */
4972         if (fsp == NULL) {
4973                 uint32_t access_mask = SEC_STD_READ_CONTROL|
4974                                         FILE_READ_ATTRIBUTES|
4975                                         FILE_WRITE_ATTRIBUTES;
4976
4977                 status = get_posix_fsp(conn,
4978                                         req,
4979                                         smb_fname,
4980                                         access_mask,
4981                                         &fsp);
4982
4983                 if (!NT_STATUS_IS_OK(status)) {
4984                         goto out;
4985                 }
4986                 close_fsp = true;
4987         }
4988
4989         SMB_ASSERT(fsp != NULL);
4990
4991         status = refuse_symlink(conn,
4992                                 fsp,
4993                                 fsp->fsp_name);
4994         if (!NT_STATUS_IS_OK(status)) {
4995                 goto out;
4996         }
4997
4998         file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp,
4999                                         talloc_tos());
5000
5001         if (file_acl == NULL && no_acl_syscall_error(errno)) {
5002                 DBG_INFO("ACLs not implemented on "
5003                         "filesystem containing %s\n",
5004                         fsp_str_dbg(fsp));
5005                 status = NT_STATUS_NOT_IMPLEMENTED;
5006                 goto out;
5007         }
5008
5009         if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
5010                 /*
5011                  * We can only have default POSIX ACLs on
5012                  * directories.
5013                  */
5014                 if (!fsp->fsp_flags.is_directory) {
5015                         DBG_INFO("Non-directory open %s\n",
5016                                 fsp_str_dbg(fsp));
5017                         status = NT_STATUS_INVALID_HANDLE;
5018                         goto out;
5019                 }
5020                 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn,
5021                                         fsp->fsp_name,
5022                                         SMB_ACL_TYPE_DEFAULT,
5023                                         talloc_tos());
5024                 def_acl = free_empty_sys_acl(conn, def_acl);
5025         }
5026
5027         num_file_acls = count_acl_entries(conn, file_acl);
5028         num_def_acls = count_acl_entries(conn, def_acl);
5029
5030         /* Wrap checks. */
5031         if (num_file_acls + num_def_acls < num_file_acls) {
5032                 status = NT_STATUS_INVALID_PARAMETER;
5033                 goto out;
5034         }
5035
5036         size_needed = num_file_acls + num_def_acls;
5037
5038         /*
5039          * (size_needed * SMB_POSIX_ACL_ENTRY_SIZE) must be less
5040          * than UINT_MAX, so check by division.
5041          */
5042         if (size_needed > (UINT_MAX/SMB_POSIX_ACL_ENTRY_SIZE)) {
5043                 status = NT_STATUS_INVALID_PARAMETER;
5044                 goto out;
5045         }
5046
5047         size_needed = size_needed*SMB_POSIX_ACL_ENTRY_SIZE;
5048         if (size_needed + SMB_POSIX_ACL_HEADER_SIZE < size_needed) {
5049                 status = NT_STATUS_INVALID_PARAMETER;
5050                 goto out;
5051         }
5052         size_needed += SMB_POSIX_ACL_HEADER_SIZE;
5053
5054         if ( data_size_in < size_needed) {
5055                 DBG_INFO("data_size too small (%u) need %u\n",
5056                         data_size_in,
5057                         size_needed);
5058                 status = NT_STATUS_BUFFER_TOO_SMALL;
5059                 goto out;
5060         }
5061
5062         SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
5063         SSVAL(pdata,2,num_file_acls);
5064         SSVAL(pdata,4,num_def_acls);
5065         pdata += SMB_POSIX_ACL_HEADER_SIZE;
5066
5067         ok = marshall_posix_acl(conn,
5068                         pdata,
5069                         &fsp->fsp_name->st,
5070                         file_acl);
5071         if (!ok) {
5072                 status = NT_STATUS_INTERNAL_ERROR;
5073                 goto out;
5074         }
5075         pdata += (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE);
5076
5077         ok = marshall_posix_acl(conn,
5078                         pdata,
5079                         &fsp->fsp_name->st,
5080                         def_acl);
5081         if (!ok) {
5082                 status = NT_STATUS_INTERNAL_ERROR;
5083                 goto out;
5084         }
5085
5086         *pdata_size_out = size_needed;
5087         status = NT_STATUS_OK;
5088
5089   out:
5090
5091         if (close_fsp) {
5092                 /*
5093                  * Ensure the stat struct in smb_fname is up to
5094                  * date. Structure copy.
5095                  */
5096                 smb_fname->st = fsp->fsp_name->st;
5097                 (void)close_file(req, fsp, NORMAL_CLOSE);
5098                 fsp = NULL;
5099         }
5100
5101         TALLOC_FREE(file_acl);
5102         TALLOC_FREE(def_acl);
5103         return status;
5104 }
5105 #endif
5106
5107 /****************************************************************************
5108  Reply to a TRANSACT2_QFILEINFO on a PIPE !
5109 ****************************************************************************/
5110
5111 static void call_trans2qpipeinfo(connection_struct *conn,
5112                                  struct smb_request *req,
5113                                  unsigned int tran_call,
5114                                  char **pparams, int total_params,
5115                                  char **ppdata, int total_data,
5116                                  unsigned int max_data_bytes)
5117 {
5118         char *params = *pparams;
5119         char *pdata = *ppdata;
5120         unsigned int data_size = 0;
5121         unsigned int param_size = 2;
5122         uint16_t info_level;
5123         files_struct *fsp;
5124
5125         if (!params) {
5126                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5127                 return;
5128         }
5129
5130         if (total_params < 4) {
5131                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5132                 return;
5133         }
5134
5135         fsp = file_fsp(req, SVAL(params,0));
5136         if (!fsp_is_np(fsp)) {
5137                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
5138                 return;
5139         }
5140
5141         info_level = SVAL(params,2);
5142
5143         *pparams = (char *)SMB_REALLOC(*pparams,2);
5144         if (*pparams == NULL) {
5145                 reply_nterror(req, NT_STATUS_NO_MEMORY);
5146                 return;
5147         }
5148         params = *pparams;
5149         SSVAL(params,0,0);
5150         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
5151                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5152                 return;
5153         }
5154         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
5155         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 
5156         if (*ppdata == NULL ) {
5157                 reply_nterror(req, NT_STATUS_NO_MEMORY);
5158                 return;
5159         }
5160         pdata = *ppdata;
5161
5162         switch (info_level) {
5163                 case SMB_FILE_STANDARD_INFORMATION:
5164                         memset(pdata,0,24);
5165                         SOFF_T(pdata,0,4096LL);
5166                         SIVAL(pdata,16,1);
5167                         SIVAL(pdata,20,1);
5168                         data_size = 24;
5169                         break;
5170
5171                 default:
5172                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5173                         return;
5174         }
5175
5176         send_trans2_replies(conn, req, NT_STATUS_OK, params, param_size, *ppdata, data_size,
5177                             max_data_bytes);
5178
5179         return;
5180 }
5181
5182 NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
5183                                TALLOC_CTX *mem_ctx,
5184                                struct smb_request *req,
5185                                uint16_t info_level,
5186                                files_struct *fsp,
5187                                struct smb_filename *smb_fname,
5188                                bool delete_pending,
5189                                struct timespec write_time_ts,
5190                                struct ea_list *ea_list,
5191                                int lock_data_count,
5192                                char *lock_data,
5193                                uint16_t flags2,
5194                                unsigned int max_data_bytes,
5195                                size_t *fixed_portion,
5196                                char **ppdata,
5197                                unsigned int *pdata_size)
5198 {
5199         char *pdata = *ppdata;
5200         char *dstart, *dend;
5201         unsigned int data_size;
5202         struct timespec create_time_ts, mtime_ts, atime_ts, ctime_ts;
5203         time_t create_time, mtime, atime, c_time;
5204         SMB_STRUCT_STAT *psbuf = &smb_fname->st;
5205         char *p;
5206         char *base_name;
5207         char *dos_fname;
5208         int mode;
5209         int nlink;
5210         NTSTATUS status;
5211         uint64_t file_size = 0;
5212         uint64_t pos = 0;
5213         uint64_t allocation_size = 0;
5214         uint64_t file_id = 0;
5215         uint32_t access_mask = 0;
5216         size_t len = 0;
5217
5218         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
5219                 return NT_STATUS_INVALID_LEVEL;
5220         }
5221
5222         DEBUG(5,("smbd_do_qfilepathinfo: %s (%s) level=%d max_data=%u\n",
5223                  smb_fname_str_dbg(smb_fname),
5224                  fsp_fnum_dbg(fsp),
5225                  info_level, max_data_bytes));
5226
5227         mode = dos_mode(conn, smb_fname);
5228         nlink = psbuf->st_ex_nlink;
5229
5230         if (nlink && (mode&FILE_ATTRIBUTE_DIRECTORY)) {
5231                 nlink = 1;
5232         }
5233
5234         if ((nlink > 0) && delete_pending) {
5235                 nlink -= 1;
5236         }
5237
5238         if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
5239                 return NT_STATUS_INVALID_PARAMETER;
5240         }
5241
5242         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
5243         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 
5244         if (*ppdata == NULL) {
5245                 return NT_STATUS_NO_MEMORY;
5246         }
5247         pdata = *ppdata;
5248         dstart = pdata;
5249         dend = dstart + data_size - 1;
5250
5251         if (!is_omit_timespec(&write_time_ts) &&
5252             !INFO_LEVEL_IS_UNIX(info_level))
5253         {
5254                 update_stat_ex_mtime(psbuf, write_time_ts);
5255         }
5256
5257         create_time_ts = get_create_timespec(conn, fsp, smb_fname);
5258         mtime_ts = psbuf->st_ex_mtime;
5259         atime_ts = psbuf->st_ex_atime;
5260         ctime_ts = get_change_timespec(conn, fsp, smb_fname);
5261
5262         if (lp_dos_filetime_resolution(SNUM(conn))) {
5263                 dos_filetime_timespec(&create_time_ts);
5264                 dos_filetime_timespec(&mtime_ts);
5265                 dos_filetime_timespec(&atime_ts);
5266                 dos_filetime_timespec(&ctime_ts);
5267         }
5268
5269         create_time = convert_timespec_to_time_t(create_time_ts);
5270         mtime = convert_timespec_to_time_t(mtime_ts);
5271         atime = convert_timespec_to_time_t(atime_ts);
5272         c_time = convert_timespec_to_time_t(ctime_ts);
5273
5274         p = strrchr_m(smb_fname->base_name,'/');
5275         if (!p)
5276                 base_name = smb_fname->base_name;
5277         else
5278                 base_name = p+1;
5279
5280         /* NT expects the name to be in an exact form of the *full*
5281            filename. See the trans2 torture test */
5282         if (ISDOT(base_name)) {
5283                 dos_fname = talloc_strdup(mem_ctx, "\\");
5284                 if (!dos_fname) {
5285                         return NT_STATUS_NO_MEMORY;
5286                 }
5287         } else {
5288                 dos_fname = talloc_asprintf(mem_ctx,
5289                                 "\\%s",
5290                                 smb_fname->base_name);
5291                 if (!dos_fname) {
5292                         return NT_STATUS_NO_MEMORY;
5293                 }
5294                 if (is_ntfs_stream_smb_fname(smb_fname)) {
5295                         dos_fname = talloc_asprintf(dos_fname, "%s",
5296                                                     smb_fname->stream_name);
5297                         if (!dos_fname) {
5298                                 return NT_STATUS_NO_MEMORY;
5299                         }
5300                 }
5301
5302                 string_replace(dos_fname, '/', '\\');
5303         }
5304
5305         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, psbuf);
5306
5307         if (!fsp) {
5308                 /* Do we have this path open ? */
5309                 files_struct *fsp1;
5310                 struct file_id fileid = vfs_file_id_from_sbuf(conn, psbuf);
5311                 fsp1 = file_find_di_first(conn->sconn, fileid);
5312                 if (fsp1 && fsp1->initial_allocation_size) {
5313                         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, psbuf);
5314                 }
5315         }
5316
5317         if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
5318                 file_size = get_file_size_stat(psbuf);
5319         }
5320
5321         if (fsp) {
5322                 pos = fsp->fh->position_information;
5323         }
5324
5325         if (fsp) {
5326                 access_mask = fsp->access_mask;
5327         } else {
5328                 /* GENERIC_EXECUTE mapping from Windows */
5329                 access_mask = 0x12019F;
5330         }
5331
5332         /* This should be an index number - looks like
5333            dev/ino to me :-)
5334
5335            I think this causes us to fail the IFSKIT
5336            BasicFileInformationTest. -tpot */
5337         file_id = SMB_VFS_FS_FILE_ID(conn, psbuf);
5338
5339         *fixed_portion = 0;
5340
5341         switch (info_level) {
5342                 case SMB_INFO_STANDARD:
5343                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
5344                         data_size = 22;
5345                         srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
5346                         srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
5347                         srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
5348                         SIVAL(pdata,l1_cbFile,(uint32_t)file_size);
5349                         SIVAL(pdata,l1_cbFileAlloc,(uint32_t)allocation_size);
5350                         SSVAL(pdata,l1_attrFile,mode);
5351                         break;
5352
5353                 case SMB_INFO_QUERY_EA_SIZE:
5354                 {
5355                         unsigned int ea_size =
5356                             estimate_ea_size(conn, fsp,
5357                                              smb_fname);
5358                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
5359                         data_size = 26;
5360                         srv_put_dos_date2(pdata,0,create_time);
5361                         srv_put_dos_date2(pdata,4,atime);
5362                         srv_put_dos_date2(pdata,8,mtime); /* write time */
5363                         SIVAL(pdata,12,(uint32_t)file_size);
5364                         SIVAL(pdata,16,(uint32_t)allocation_size);
5365                         SSVAL(pdata,20,mode);
5366                         SIVAL(pdata,22,ea_size);
5367                         break;
5368                 }
5369
5370                 case SMB_INFO_IS_NAME_VALID:
5371                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
5372                         if (fsp) {
5373                                 /* os/2 needs this ? really ?*/
5374                                 return NT_STATUS_DOS(ERRDOS, ERRbadfunc);
5375                         }
5376                         /* This is only reached for qpathinfo */
5377                         data_size = 0;
5378                         break;
5379
5380                 case SMB_INFO_QUERY_EAS_FROM_LIST:
5381                 {
5382                         size_t total_ea_len = 0;
5383                         struct ea_list *ea_file_list = NULL;
5384                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
5385
5386                         status =
5387                             get_ea_list_from_file(mem_ctx, conn, fsp,
5388                                                   smb_fname,
5389                                                   &total_ea_len, &ea_file_list);
5390                         if (!NT_STATUS_IS_OK(status)) {
5391                                 return status;
5392                         }
5393
5394                         ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
5395
5396                         if (!ea_list || (total_ea_len > data_size)) {
5397                                 data_size = 4;
5398                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
5399                                 break;
5400                         }
5401
5402                         data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
5403                         break;
5404                 }
5405
5406                 case SMB_INFO_QUERY_ALL_EAS:
5407                 {
5408                         /* We have data_size bytes to put EA's into. */
5409                         size_t total_ea_len = 0;
5410                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
5411
5412                         status = get_ea_list_from_file(mem_ctx, conn, fsp,
5413                                                         smb_fname,
5414                                                         &total_ea_len, &ea_list);
5415                         if (!NT_STATUS_IS_OK(status)) {
5416                                 return status;
5417                         }
5418
5419                         if (!ea_list || (total_ea_len > data_size)) {
5420                                 data_size = 4;
5421                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
5422                                 break;
5423                         }
5424
5425                         data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
5426                         break;
5427                 }
5428
5429                 case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
5430                 {
5431                         /* This is FileFullEaInformation - 0xF which maps to
5432                          * 1015 (decimal) in smbd_do_setfilepathinfo. */
5433
5434                         /* We have data_size bytes to put EA's into. */
5435                         size_t total_ea_len = 0;
5436                         struct ea_list *ea_file_list = NULL;
5437
5438                         DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
5439
5440                         /*TODO: add filtering and index handling */
5441
5442                         status  =
5443                                 get_ea_list_from_file(mem_ctx, conn, fsp,
5444                                                   smb_fname,
5445                                                   &total_ea_len, &ea_file_list);
5446                         if (!NT_STATUS_IS_OK(status)) {
5447                                 return status;
5448                         }
5449                         if (!ea_file_list) {
5450                                 return NT_STATUS_NO_EAS_ON_FILE;
5451                         }
5452
5453                         status = fill_ea_chained_buffer(mem_ctx,
5454                                                         pdata,
5455                                                         data_size,
5456                                                         &data_size,
5457                                                         conn, ea_file_list);
5458                         if (!NT_STATUS_IS_OK(status)) {
5459                                 return status;
5460                         }
5461                         break;
5462                 }
5463
5464                 case SMB_FILE_BASIC_INFORMATION:
5465                 case SMB_QUERY_FILE_BASIC_INFO:
5466
5467                         if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
5468                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
5469                                 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
5470                         } else {
5471                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
5472                                 data_size = 40;
5473                                 SIVAL(pdata,36,0);
5474                         }
5475                         put_long_date_full_timespec(conn->ts_res,pdata,&create_time_ts);
5476                         put_long_date_full_timespec(conn->ts_res,pdata+8,&atime_ts);
5477                         put_long_date_full_timespec(conn->ts_res,pdata+16,&mtime_ts); /* write time */
5478                         put_long_date_full_timespec(conn->ts_res,pdata+24,&ctime_ts); /* change time */
5479                         SIVAL(pdata,32,mode);
5480
5481                         DEBUG(5,("SMB_QFBI - "));
5482                         DEBUG(5,("create: %s ", ctime(&create_time)));
5483                         DEBUG(5,("access: %s ", ctime(&atime)));
5484                         DEBUG(5,("write: %s ", ctime(&mtime)));
5485                         DEBUG(5,("change: %s ", ctime(&c_time)));
5486                         DEBUG(5,("mode: %x\n", mode));
5487                         *fixed_portion = data_size;
5488                         break;
5489
5490                 case SMB_FILE_STANDARD_INFORMATION:
5491                 case SMB_QUERY_FILE_STANDARD_INFO:
5492
5493                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
5494                         data_size = 24;
5495                         SOFF_T(pdata,0,allocation_size);
5496                         SOFF_T(pdata,8,file_size);
5497                         SIVAL(pdata,16,nlink);
5498                         SCVAL(pdata,20,delete_pending?1:0);
5499                         SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
5500                         SSVAL(pdata,22,0); /* Padding. */
5501                         *fixed_portion = 24;
5502                         break;
5503
5504                 case SMB_FILE_EA_INFORMATION:
5505                 case SMB_QUERY_FILE_EA_INFO:
5506                 {
5507                         unsigned int ea_size =
5508                             estimate_ea_size(conn, fsp, smb_fname);
5509                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
5510                         data_size = 4;
5511                         *fixed_portion = 4;
5512                         SIVAL(pdata,0,ea_size);
5513                         break;
5514                 }
5515
5516                 /* Get the 8.3 name - used if NT SMB was negotiated. */
5517                 case SMB_QUERY_FILE_ALT_NAME_INFO:
5518                 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
5519                 {
5520                         char mangled_name[13];
5521                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
5522                         if (!name_to_8_3(base_name,mangled_name,
5523                                                 True,conn->params)) {
5524                                 return NT_STATUS_NO_MEMORY;
5525                         }
5526                         status = srvstr_push(dstart, flags2,
5527                                           pdata+4, mangled_name,
5528                                           PTR_DIFF(dend, pdata+4),
5529                                           STR_UNICODE, &len);
5530                         if (!NT_STATUS_IS_OK(status)) {
5531                                 return status;
5532                         }
5533                         data_size = 4 + len;
5534                         SIVAL(pdata,0,len);
5535                         *fixed_portion = 8;
5536                         break;
5537                 }
5538
5539                 case SMB_QUERY_FILE_NAME_INFO:
5540                 {
5541                         /*
5542                           this must be *exactly* right for ACLs on mapped drives to work
5543                          */
5544                         status = srvstr_push(dstart, flags2,
5545                                           pdata+4, dos_fname,
5546                                           PTR_DIFF(dend, pdata+4),
5547                                           STR_UNICODE, &len);
5548                         if (!NT_STATUS_IS_OK(status)) {
5549                                 return status;
5550                         }
5551                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
5552                         data_size = 4 + len;
5553                         SIVAL(pdata,0,len);
5554                         break;
5555                 }
5556
5557                 case SMB_FILE_NORMALIZED_NAME_INFORMATION:
5558                 {
5559                         char *nfname = NULL;
5560
5561                         if (fsp == NULL || !fsp->conn->sconn->using_smb2) {
5562                                 return NT_STATUS_INVALID_LEVEL;
5563                         }
5564
5565                         nfname = talloc_strdup(mem_ctx, smb_fname->base_name);
5566                         if (nfname == NULL) {
5567                                 return NT_STATUS_NO_MEMORY;
5568                         }
5569
5570                         if (ISDOT(nfname)) {
5571                                 nfname[0] = '\0';
5572                         }
5573                         string_replace(nfname, '/', '\\');
5574
5575                         if (smb_fname->stream_name != NULL) {
5576                                 const char *s = smb_fname->stream_name;
5577                                 const char *e = NULL;
5578                                 size_t n;
5579
5580                                 SMB_ASSERT(s[0] != '\0');
5581
5582                                 /*
5583                                  * smb_fname->stream_name is in form
5584                                  * of ':StrEam:$DATA', but we should only
5585                                  * append ':StrEam' here.
5586                                  */
5587
5588                                 e = strchr(&s[1], ':');
5589                                 if (e == NULL) {
5590                                         n = strlen(s);
5591                                 } else {
5592                                         n = PTR_DIFF(e, s);
5593                                 }
5594                                 nfname = talloc_strndup_append(nfname, s, n);
5595                                 if (nfname == NULL) {
5596                                         return NT_STATUS_NO_MEMORY;
5597                                 }
5598                         }
5599
5600                         status = srvstr_push(dstart, flags2,
5601                                           pdata+4, nfname,
5602                                           PTR_DIFF(dend, pdata+4),
5603                                           STR_UNICODE, &len);
5604                         if (!NT_STATUS_IS_OK(status)) {
5605                                 return status;
5606                         }
5607                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NORMALIZED_NAME_INFORMATION\n"));
5608                         data_size = 4 + len;
5609                         SIVAL(pdata,0,len);
5610                         *fixed_portion = 8;
5611                         break;
5612                 }
5613
5614                 case SMB_FILE_ALLOCATION_INFORMATION:
5615                 case SMB_QUERY_FILE_ALLOCATION_INFO:
5616                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
5617                         data_size = 8;
5618                         SOFF_T(pdata,0,allocation_size);
5619                         break;
5620
5621                 case SMB_FILE_END_OF_FILE_INFORMATION:
5622                 case SMB_QUERY_FILE_END_OF_FILEINFO:
5623                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
5624                         data_size = 8;
5625                         SOFF_T(pdata,0,file_size);
5626                         break;
5627
5628                 case SMB_QUERY_FILE_ALL_INFO:
5629                 case SMB_FILE_ALL_INFORMATION:
5630                 {
5631                         unsigned int ea_size =
5632                             estimate_ea_size(conn, fsp, smb_fname);
5633                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
5634                         put_long_date_full_timespec(conn->ts_res,pdata,&create_time_ts);
5635                         put_long_date_full_timespec(conn->ts_res,pdata+8,&atime_ts);
5636                         put_long_date_full_timespec(conn->ts_res,pdata+16,&mtime_ts); /* write time */
5637                         put_long_date_full_timespec(conn->ts_res,pdata+24,&ctime_ts); /* change time */
5638                         SIVAL(pdata,32,mode);
5639                         SIVAL(pdata,36,0); /* padding. */
5640                         pdata += 40;
5641                         SOFF_T(pdata,0,allocation_size);
5642                         SOFF_T(pdata,8,file_size);
5643                         SIVAL(pdata,16,nlink);
5644                         SCVAL(pdata,20,delete_pending);
5645                         SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
5646                         SSVAL(pdata,22,0);
5647                         pdata += 24;
5648                         SIVAL(pdata,0,ea_size);
5649                         pdata += 4; /* EA info */
5650                         status = srvstr_push(dstart, flags2,
5651                                           pdata+4, dos_fname,
5652                                           PTR_DIFF(dend, pdata+4),
5653                                           STR_UNICODE, &len);
5654                         if (!NT_STATUS_IS_OK(status)) {
5655                                 return status;
5656                         }
5657                         SIVAL(pdata,0,len);
5658                         pdata += 4 + len;
5659                         data_size = PTR_DIFF(pdata,(*ppdata));
5660                         *fixed_portion = 10;
5661                         break;
5662                 }
5663
5664                 case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
5665                 {
5666                         unsigned int ea_size =
5667                             estimate_ea_size(conn, fsp, smb_fname);
5668                         DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
5669                         put_long_date_full_timespec(conn->ts_res,pdata+0x00,&create_time_ts);
5670                         put_long_date_full_timespec(conn->ts_res,pdata+0x08,&atime_ts);
5671                         put_long_date_full_timespec(conn->ts_res,pdata+0x10,&mtime_ts); /* write time */
5672                         put_long_date_full_timespec(conn->ts_res,pdata+0x18,&ctime_ts); /* change time */
5673                         SIVAL(pdata,    0x20, mode);
5674                         SIVAL(pdata,    0x24, 0); /* padding. */
5675                         SBVAL(pdata,    0x28, allocation_size);
5676                         SBVAL(pdata,    0x30, file_size);
5677                         SIVAL(pdata,    0x38, nlink);
5678                         SCVAL(pdata,    0x3C, delete_pending);
5679                         SCVAL(pdata,    0x3D, (mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
5680                         SSVAL(pdata,    0x3E, 0); /* padding */
5681                         SBVAL(pdata,    0x40, file_id);
5682                         SIVAL(pdata,    0x48, ea_size);
5683                         SIVAL(pdata,    0x4C, access_mask);
5684                         SBVAL(pdata,    0x50, pos);
5685                         SIVAL(pdata,    0x58, mode); /*TODO: mode != mode fix this!!! */
5686                         SIVAL(pdata,    0x5C, 0); /* No alignment needed. */
5687
5688                         pdata += 0x60;
5689
5690                         status = srvstr_push(dstart, flags2,
5691                                           pdata+4, dos_fname,
5692                                           PTR_DIFF(dend, pdata+4),
5693                                           STR_UNICODE, &len);
5694                         if (!NT_STATUS_IS_OK(status)) {
5695                                 return status;
5696                         }
5697                         SIVAL(pdata,0,len);
5698                         pdata += 4 + len;
5699                         data_size = PTR_DIFF(pdata,(*ppdata));
5700                         *fixed_portion = 104;
5701                         break;
5702                 }
5703                 case SMB_FILE_INTERNAL_INFORMATION:
5704
5705                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
5706                         SBVAL(pdata, 0, file_id);
5707                         data_size = 8;
5708                         *fixed_portion = 8;
5709                         break;
5710
5711                 case SMB_FILE_ACCESS_INFORMATION:
5712                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
5713                         SIVAL(pdata, 0, access_mask);
5714                         data_size = 4;
5715                         *fixed_portion = 4;
5716                         break;
5717
5718                 case SMB_FILE_NAME_INFORMATION:
5719                         /* Pathname with leading '\'. */
5720                         {
5721                                 size_t byte_len;
5722                                 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
5723                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
5724                                 SIVAL(pdata,0,byte_len);
5725                                 data_size = 4 + byte_len;
5726                                 break;
5727                         }
5728
5729                 case SMB_FILE_DISPOSITION_INFORMATION:
5730                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
5731                         data_size = 1;
5732                         SCVAL(pdata,0,delete_pending);
5733                         *fixed_portion = 1;
5734                         break;
5735
5736                 case SMB_FILE_POSITION_INFORMATION:
5737                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
5738                         data_size = 8;
5739                         SOFF_T(pdata,0,pos);
5740                         *fixed_portion = 8;
5741                         break;
5742
5743                 case SMB_FILE_MODE_INFORMATION:
5744                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
5745                         SIVAL(pdata,0,mode);
5746                         data_size = 4;
5747                         *fixed_portion = 4;
5748                         break;
5749
5750                 case SMB_FILE_ALIGNMENT_INFORMATION:
5751                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
5752                         SIVAL(pdata,0,0); /* No alignment needed. */
5753                         data_size = 4;
5754                         *fixed_portion = 4;
5755                         break;
5756
5757                 /*
5758                  * NT4 server just returns "invalid query" to this - if we try
5759                  * to answer it then NTws gets a BSOD! (tridge).  W2K seems to
5760                  * want this. JRA.
5761                  */
5762                 /* The first statement above is false - verified using Thursby
5763                  * client against NT4 -- gcolley.
5764                  */
5765                 case SMB_QUERY_FILE_STREAM_INFO:
5766                 case SMB_FILE_STREAM_INFORMATION: {
5767                         unsigned int num_streams = 0;
5768                         struct stream_struct *streams = NULL;
5769
5770                         DEBUG(10,("smbd_do_qfilepathinfo: "
5771                                   "SMB_FILE_STREAM_INFORMATION\n"));
5772
5773                         if (is_ntfs_stream_smb_fname(smb_fname)) {
5774                                 return NT_STATUS_INVALID_PARAMETER;
5775                         }
5776
5777                         status = vfs_streaminfo(conn,
5778                                                 fsp,
5779                                                 smb_fname,
5780                                                 talloc_tos(),
5781                                                 &num_streams,
5782                                                 &streams);
5783
5784                         if (!NT_STATUS_IS_OK(status)) {
5785                                 DEBUG(10, ("could not get stream info: %s\n",
5786                                            nt_errstr(status)));
5787                                 return status;
5788                         }
5789
5790                         status = marshall_stream_info(num_streams, streams,
5791                                                       pdata, max_data_bytes,
5792                                                       &data_size);
5793
5794                         if (!NT_STATUS_IS_OK(status)) {
5795                                 DEBUG(10, ("marshall_stream_info failed: %s\n",
5796                                            nt_errstr(status)));
5797                                 TALLOC_FREE(streams);
5798                                 return status;
5799                         }
5800
5801                         TALLOC_FREE(streams);
5802
5803                         *fixed_portion = 32;
5804
5805                         break;
5806                 }
5807                 case SMB_QUERY_COMPRESSION_INFO:
5808                 case SMB_FILE_COMPRESSION_INFORMATION:
5809                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
5810                         SOFF_T(pdata,0,file_size);
5811                         SIVAL(pdata,8,0); /* ??? */
5812                         SIVAL(pdata,12,0); /* ??? */
5813                         data_size = 16;
5814                         *fixed_portion = 16;
5815                         break;
5816
5817                 case SMB_FILE_NETWORK_OPEN_INFORMATION:
5818                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
5819                         put_long_date_full_timespec(conn->ts_res,pdata,&create_time_ts);
5820                         put_long_date_full_timespec(conn->ts_res,pdata+8,&atime_ts);
5821                         put_long_date_full_timespec(conn->ts_res,pdata+16,&mtime_ts); /* write time */
5822                         put_long_date_full_timespec(conn->ts_res,pdata+24,&ctime_ts); /* change time */
5823                         SOFF_T(pdata,32,allocation_size);
5824                         SOFF_T(pdata,40,file_size);
5825                         SIVAL(pdata,48,mode);
5826                         SIVAL(pdata,52,0); /* ??? */
5827                         data_size = 56;
5828                         *fixed_portion = 56;
5829                         break;
5830
5831                 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
5832                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
5833                         SIVAL(pdata,0,mode);
5834                         SIVAL(pdata,4,0);
5835                         data_size = 8;
5836                         *fixed_portion = 8;
5837                         break;
5838
5839                 /*
5840                  * CIFS UNIX Extensions.
5841                  */
5842
5843                 case SMB_QUERY_FILE_UNIX_BASIC:
5844
5845                         pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
5846                         data_size = PTR_DIFF(pdata,(*ppdata));
5847
5848                         DEBUG(4,("smbd_do_qfilepathinfo: "
5849                                  "SMB_QUERY_FILE_UNIX_BASIC\n"));
5850                         dump_data(4, (uint8_t *)(*ppdata), data_size);
5851
5852                         break;
5853
5854                 case SMB_QUERY_FILE_UNIX_INFO2:
5855
5856                         pdata = store_file_unix_basic_info2(conn, pdata, fsp, psbuf);
5857                         data_size = PTR_DIFF(pdata,(*ppdata));
5858
5859                         {
5860                                 int i;
5861                                 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
5862
5863                                 for (i=0; i<100; i++)
5864                                         DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
5865                                 DEBUG(4,("\n"));
5866                         }
5867
5868                         break;
5869
5870                 case SMB_QUERY_FILE_UNIX_LINK:
5871                         {
5872                                 int link_len = 0;
5873                                 char *buffer = talloc_array(mem_ctx, char, PATH_MAX+1);
5874
5875                                 if (!buffer) {
5876                                         return NT_STATUS_NO_MEMORY;
5877                                 }
5878
5879                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
5880 #ifdef S_ISLNK
5881                                 if(!S_ISLNK(psbuf->st_ex_mode)) {
5882                                         return NT_STATUS_DOS(ERRSRV, ERRbadlink);
5883                                 }
5884 #else
5885                                 return NT_STATUS_DOS(ERRDOS, ERRbadlink);
5886 #endif
5887                                 link_len = SMB_VFS_READLINKAT(conn,
5888                                                         conn->cwd_fsp,
5889                                                         smb_fname,
5890                                                         buffer,
5891                                                         PATH_MAX);
5892
5893                                 if (link_len == -1) {
5894                                         return map_nt_error_from_unix(errno);
5895                                 }
5896                                 buffer[link_len] = 0;
5897                                 status = srvstr_push(dstart, flags2,
5898                                                   pdata, buffer,
5899                                                   PTR_DIFF(dend, pdata),
5900                                                   STR_TERMINATE, &len);
5901                                 if (!NT_STATUS_IS_OK(status)) {
5902                                         return status;
5903                                 }
5904                                 pdata += len;
5905                                 data_size = PTR_DIFF(pdata,(*ppdata));
5906
5907                                 break;
5908                         }
5909
5910 #if defined(HAVE_POSIX_ACLS)
5911                 case SMB_QUERY_POSIX_ACL:
5912                         {
5913                                 status = smb_query_posix_acl(conn,
5914                                                         req,
5915                                                         fsp,
5916                                                         smb_fname,
5917                                                         pdata,
5918                                                         data_size,
5919                                                         &data_size);
5920                                 if (!NT_STATUS_IS_OK(status)) {
5921                                         return status;
5922                                 }
5923                                 break;
5924                         }
5925 #endif
5926
5927
5928                 case SMB_QUERY_POSIX_LOCK:
5929                 {
5930                         uint64_t count;
5931                         uint64_t offset;
5932                         uint64_t smblctx;
5933                         enum brl_type lock_type;
5934
5935                         /* We need an open file with a real fd for this. */
5936                         if (!fsp || fsp->fh->fd == -1) {
5937                                 return NT_STATUS_INVALID_LEVEL;
5938                         }
5939
5940                         if (lock_data_count != POSIX_LOCK_DATA_SIZE) {
5941                                 return NT_STATUS_INVALID_PARAMETER;
5942                         }
5943
5944                         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
5945                                 case POSIX_LOCK_TYPE_READ:
5946                                         lock_type = READ_LOCK;
5947                                         break;
5948                                 case POSIX_LOCK_TYPE_WRITE:
5949                                         lock_type = WRITE_LOCK;
5950                                         break;
5951                                 case POSIX_LOCK_TYPE_UNLOCK:
5952                                 default:
5953                                         /* There's no point in asking for an unlock... */
5954                                         return NT_STATUS_INVALID_PARAMETER;
5955                         }
5956
5957                         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
5958                         offset = BVAL(pdata,POSIX_LOCK_START_OFFSET);
5959                         count = BVAL(pdata,POSIX_LOCK_LEN_OFFSET);
5960
5961                         status = query_lock(fsp,
5962                                         &smblctx,
5963                                         &count,
5964                                         &offset,
5965                                         &lock_type,
5966                                         POSIX_LOCK);
5967
5968                         if (ERROR_WAS_LOCK_DENIED(status)) {
5969                                 /* Here we need to report who has it locked... */
5970                                 data_size = POSIX_LOCK_DATA_SIZE;
5971
5972                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
5973                                 SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
5974                                 SIVAL(pdata, POSIX_LOCK_PID_OFFSET, (uint32_t)smblctx);
5975                                 SBVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
5976                                 SBVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
5977
5978                         } else if (NT_STATUS_IS_OK(status)) {
5979                                 /* For success we just return a copy of what we sent
5980                                    with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
5981                                 data_size = POSIX_LOCK_DATA_SIZE;
5982                                 memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
5983                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
5984                         } else {
5985                                 return status;
5986                         }
5987                         break;
5988                 }
5989
5990                 default:
5991                         return NT_STATUS_INVALID_LEVEL;
5992         }
5993
5994         *pdata_size = data_size;
5995         return NT_STATUS_OK;
5996 }
5997
5998 /****************************************************************************
5999  Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
6000  file name or file id).
6001 ****************************************************************************/
6002
6003 static void call_trans2qfilepathinfo(connection_struct *conn,
6004                                      struct smb_request *req,
6005                                      unsigned int tran_call,
6006                                      char **pparams, int total_params,
6007                                      char **ppdata, int total_data,
6008                                      unsigned int max_data_bytes)
6009 {
6010         char *params = *pparams;
6011         char *pdata = *ppdata;
6012         uint16_t info_level;
6013         unsigned int data_size = 0;
6014         unsigned int param_size = 2;
6015         struct smb_filename *smb_fname = NULL;
6016         bool delete_pending = False;
6017         struct timespec write_time_ts;
6018         files_struct *fsp = NULL;
6019         struct file_id fileid;
6020         struct ea_list *ea_list = NULL;
6021         int lock_data_count = 0;
6022         char *lock_data = NULL;
6023         size_t fixed_portion;
6024         NTSTATUS status = NT_STATUS_OK;
6025
6026         if (!params) {
6027                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6028                 return;
6029         }
6030
6031         ZERO_STRUCT(write_time_ts);
6032
6033         if (tran_call == TRANSACT2_QFILEINFO) {
6034                 if (total_params < 4) {
6035                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6036                         return;
6037                 }
6038
6039                 if (IS_IPC(conn)) {
6040                         call_trans2qpipeinfo(conn, req, tran_call,
6041                                              pparams, total_params,
6042                                              ppdata, total_data,
6043                                              max_data_bytes);
6044                         return;
6045                 }
6046
6047                 fsp = file_fsp(req, SVAL(params,0));
6048                 info_level = SVAL(params,2);
6049
6050                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
6051
6052                 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
6053                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
6054                         return;
6055                 }
6056
6057                 /* Initial check for valid fsp ptr. */
6058                 if (!check_fsp_open(conn, req, fsp)) {
6059                         return;
6060                 }
6061
6062                 smb_fname = cp_smb_filename(talloc_tos(), fsp->fsp_name);
6063                 if (smb_fname == NULL) {
6064                         reply_nterror(req, NT_STATUS_NO_MEMORY);
6065                         return;
6066                 }
6067
6068                 if(fsp->fake_file_handle) {
6069                         /*
6070                          * This is actually for the QUOTA_FAKE_FILE --metze
6071                          */
6072
6073                         /* We know this name is ok, it's already passed the checks. */
6074
6075                 } else if(fsp->fh->fd == -1) {
6076                         /*
6077                          * This is actually a QFILEINFO on a directory
6078                          * handle (returned from an NT SMB). NT5.0 seems
6079                          * to do this call. JRA.
6080                          */
6081
6082                         if (INFO_LEVEL_IS_UNIX(info_level)) {
6083                                 /* Always do lstat for UNIX calls. */
6084                                 if (SMB_VFS_LSTAT(conn, smb_fname)) {
6085                                         DEBUG(3,("call_trans2qfilepathinfo: "
6086                                                  "SMB_VFS_LSTAT of %s failed "
6087                                                  "(%s)\n",
6088                                                  smb_fname_str_dbg(smb_fname),
6089                                                  strerror(errno)));
6090                                         reply_nterror(req,
6091                                                 map_nt_error_from_unix(errno));
6092                                         return;
6093                                 }
6094                         } else if (SMB_VFS_STAT(conn, smb_fname)) {
6095                                 DEBUG(3,("call_trans2qfilepathinfo: "
6096                                          "SMB_VFS_STAT of %s failed (%s)\n",
6097                                          smb_fname_str_dbg(smb_fname),
6098                                          strerror(errno)));
6099                                 reply_nterror(req,
6100                                         map_nt_error_from_unix(errno));
6101                                 return;
6102                         }
6103
6104                         if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
6105                                 fileid = vfs_file_id_from_sbuf(
6106                                         conn, &smb_fname->st);
6107                                 get_file_infos(fileid, fsp->name_hash,
6108                                                &delete_pending,
6109                                                &write_time_ts);
6110                         }
6111                 } else {
6112                         /*
6113                          * Original code - this is an open file.
6114                          */
6115                         if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
6116                                 DEBUG(3, ("fstat of %s failed (%s)\n",
6117                                           fsp_fnum_dbg(fsp), strerror(errno)));
6118                                 reply_nterror(req,
6119                                         map_nt_error_from_unix(errno));
6120                                 return;
6121                         }
6122                         if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
6123                                 fileid = vfs_file_id_from_sbuf(
6124                                         conn, &smb_fname->st);
6125                                 get_file_infos(fileid, fsp->name_hash,
6126                                                &delete_pending,
6127                                                &write_time_ts);
6128                         }
6129                 }
6130
6131         } else {
6132                 uint32_t name_hash;
6133                 char *fname = NULL;
6134                 uint32_t ucf_flags = ucf_flags_from_smb_request(req);
6135
6136                 /* qpathinfo */
6137                 if (total_params < 7) {
6138                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6139                         return;
6140                 }
6141
6142                 info_level = SVAL(params,0);
6143
6144                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
6145
6146                 if (INFO_LEVEL_IS_UNIX(info_level)) {
6147                         if (!lp_unix_extensions()) {
6148                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
6149                                 return;
6150                         }
6151                         if (info_level == SMB_QUERY_FILE_UNIX_BASIC ||
6152                                         info_level == SMB_QUERY_FILE_UNIX_INFO2 ||
6153                                         info_level == SMB_QUERY_FILE_UNIX_LINK ||
6154                                         req->posix_pathnames) {
6155                                 ucf_flags |= UCF_UNIX_NAME_LOOKUP;
6156                         }
6157                 }
6158
6159                 if (req->posix_pathnames) {
6160                         srvstr_get_path_posix(req,
6161                                 params,
6162                                 req->flags2,
6163                                 &fname,
6164                                 &params[6],
6165                                 total_params - 6,
6166                                 STR_TERMINATE,
6167                                 &status);
6168                 } else {
6169                         srvstr_get_path(req,
6170                                 params,
6171                                 req->flags2,
6172                                 &fname,
6173                                 &params[6],
6174                                 total_params - 6,
6175                                 STR_TERMINATE,
6176                                 &status);
6177                 }
6178                 if (!NT_STATUS_IS_OK(status)) {
6179                         reply_nterror(req, status);
6180                         return;
6181                 }
6182
6183                 status = filename_convert(req,
6184                                         conn,
6185                                         fname,
6186                                         ucf_flags,
6187                                         0,
6188                                         NULL,
6189                                         &smb_fname);
6190                 if (!NT_STATUS_IS_OK(status)) {
6191                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6192                                 reply_botherror(req,
6193                                                 NT_STATUS_PATH_NOT_COVERED,
6194                                                 ERRSRV, ERRbadpath);
6195                                 return;
6196                         }
6197                         reply_nterror(req, status);
6198                         return;
6199                 }
6200
6201                 /* If this is a stream, check if there is a delete_pending. */
6202                 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6203                     && is_ntfs_stream_smb_fname(smb_fname)) {
6204                         struct smb_filename *smb_fname_base;
6205
6206                         /* Create an smb_filename with stream_name == NULL. */
6207                         smb_fname_base = synthetic_smb_fname(
6208                                                 talloc_tos(),
6209                                                 smb_fname->base_name,
6210                                                 NULL,
6211                                                 NULL,
6212                                                 smb_fname->twrp,
6213                                                 smb_fname->flags);
6214                         if (smb_fname_base == NULL) {
6215                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
6216                                 return;
6217                         }
6218
6219                         if (INFO_LEVEL_IS_UNIX(info_level) || req->posix_pathnames) {
6220                                 /* Always do lstat for UNIX calls. */
6221                                 if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
6222                                         DEBUG(3,("call_trans2qfilepathinfo: "
6223                                                  "SMB_VFS_LSTAT of %s failed "
6224                                                  "(%s)\n",
6225                                                  smb_fname_str_dbg(smb_fname_base),
6226                                                  strerror(errno)));
6227                                         TALLOC_FREE(smb_fname_base);
6228                                         reply_nterror(req,
6229                                                 map_nt_error_from_unix(errno));
6230                                         return;
6231                                 }
6232                         } else {
6233                                 if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
6234                                         DEBUG(3,("call_trans2qfilepathinfo: "
6235                                                  "fileinfo of %s failed "
6236                                                  "(%s)\n",
6237                                                  smb_fname_str_dbg(smb_fname_base),
6238                                                  strerror(errno)));
6239                                         TALLOC_FREE(smb_fname_base);
6240                                         reply_nterror(req,
6241                                                 map_nt_error_from_unix(errno));
6242                                         return;
6243                                 }
6244                         }
6245
6246                         status = file_name_hash(conn,
6247                                         smb_fname_str_dbg(smb_fname_base),
6248                                         &name_hash);
6249                         if (!NT_STATUS_IS_OK(status)) {
6250                                 TALLOC_FREE(smb_fname_base);
6251                                 reply_nterror(req, status);
6252                                 return;
6253                         }
6254
6255                         fileid = vfs_file_id_from_sbuf(conn,
6256                                                        &smb_fname_base->st);
6257                         TALLOC_FREE(smb_fname_base);
6258                         get_file_infos(fileid, name_hash, &delete_pending, NULL);
6259                         if (delete_pending) {
6260                                 reply_nterror(req, NT_STATUS_DELETE_PENDING);
6261                                 return;
6262                         }
6263                 }
6264
6265                 if (INFO_LEVEL_IS_UNIX(info_level) || req->posix_pathnames) {
6266                         /* Always do lstat for UNIX calls. */
6267                         if (SMB_VFS_LSTAT(conn, smb_fname)) {
6268                                 DEBUG(3,("call_trans2qfilepathinfo: "
6269                                          "SMB_VFS_LSTAT of %s failed (%s)\n",
6270                                          smb_fname_str_dbg(smb_fname),
6271                                          strerror(errno)));
6272                                 reply_nterror(req,
6273                                         map_nt_error_from_unix(errno));
6274                                 return;
6275                         }
6276
6277                 } else {
6278                         if (SMB_VFS_STAT(conn, smb_fname) != 0) {
6279                                 DEBUG(3,("call_trans2qfilepathinfo: "
6280                                          "SMB_VFS_STAT of %s failed (%s)\n",
6281                                          smb_fname_str_dbg(smb_fname),
6282                                          strerror(errno)));
6283                                 reply_nterror(req,
6284                                         map_nt_error_from_unix(errno));
6285                                 return;
6286                         }
6287                 }
6288
6289                 status = file_name_hash(conn,
6290                                 smb_fname_str_dbg(smb_fname),
6291                                 &name_hash);
6292                 if (!NT_STATUS_IS_OK(status)) {
6293                         reply_nterror(req, status);
6294                         return;
6295                 }
6296
6297                 if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
6298                         fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
6299                         get_file_infos(fileid, name_hash, &delete_pending,
6300                                        &write_time_ts);
6301                 }
6302
6303                 if (delete_pending) {
6304                         reply_nterror(req, NT_STATUS_DELETE_PENDING);
6305                         return;
6306                 }
6307         }
6308
6309         DEBUG(3,("call_trans2qfilepathinfo %s (%s) level=%d call=%d "
6310                  "total_data=%d\n", smb_fname_str_dbg(smb_fname),
6311                  fsp_fnum_dbg(fsp),
6312                  info_level,tran_call,total_data));
6313
6314         /* Pull out any data sent here before we realloc. */
6315         switch (info_level) {
6316                 case SMB_INFO_QUERY_EAS_FROM_LIST:
6317                 {
6318                         /* Pull any EA list from the data portion. */
6319                         uint32_t ea_size;
6320
6321                         if (total_data < 4) {
6322                                 reply_nterror(
6323                                         req, NT_STATUS_INVALID_PARAMETER);
6324                                 return;
6325                         }
6326                         ea_size = IVAL(pdata,0);
6327
6328                         if (total_data > 0 && ea_size != total_data) {
6329                                 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
6330 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
6331                                 reply_nterror(
6332                                         req, NT_STATUS_INVALID_PARAMETER);
6333                                 return;
6334                         }
6335
6336                         if (!lp_ea_support(SNUM(conn))) {
6337                                 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
6338                                 return;
6339                         }
6340
6341                         /* Pull out the list of names. */
6342                         ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4);
6343                         if (!ea_list) {
6344                                 reply_nterror(
6345                                         req, NT_STATUS_INVALID_PARAMETER);
6346                                 return;
6347                         }
6348                         break;
6349                 }
6350
6351                 case SMB_QUERY_POSIX_LOCK:
6352                 {
6353                         if (fsp == NULL || fsp->fh->fd == -1) {
6354                                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
6355                                 return;
6356                         }
6357
6358                         if (total_data != POSIX_LOCK_DATA_SIZE) {
6359                                 reply_nterror(
6360                                         req, NT_STATUS_INVALID_PARAMETER);
6361                                 return;
6362                         }
6363
6364                         /* Copy the lock range data. */
6365                         lock_data = (char *)talloc_memdup(
6366                                 req, pdata, total_data);
6367                         if (!lock_data) {
6368                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
6369                                 return;
6370                         }
6371                         lock_data_count = total_data;
6372                 }
6373                 default:
6374                         break;
6375         }
6376
6377         *pparams = (char *)SMB_REALLOC(*pparams,2);
6378         if (*pparams == NULL) {
6379                 reply_nterror(req, NT_STATUS_NO_MEMORY);
6380                 return;
6381         }
6382         params = *pparams;
6383         SSVAL(params,0,0);
6384
6385         /*
6386          * draft-leach-cifs-v1-spec-02.txt
6387          * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
6388          * says:
6389          *
6390          *  The requested information is placed in the Data portion of the
6391          *  transaction response. For the information levels greater than 0x100,
6392          *  the transaction response has 1 parameter word which should be
6393          *  ignored by the client.
6394          *
6395          * However Windows only follows this rule for the IS_NAME_VALID call.
6396          */
6397         switch (info_level) {
6398         case SMB_INFO_IS_NAME_VALID:
6399                 param_size = 0;
6400                 break;
6401         }
6402
6403         if ((info_level & 0xFF00) == 0xFF00) {
6404                 /*
6405                  * We use levels that start with 0xFF00
6406                  * internally to represent SMB2 specific levels
6407                  */
6408                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
6409                 return;
6410         }
6411
6412         status = smbd_do_qfilepathinfo(conn, req, req, info_level,
6413                                        fsp, smb_fname,
6414                                        delete_pending, write_time_ts,
6415                                        ea_list,
6416                                        lock_data_count, lock_data,
6417                                        req->flags2, max_data_bytes,
6418                                        &fixed_portion,
6419                                        ppdata, &data_size);
6420         if (!NT_STATUS_IS_OK(status)) {
6421                 if (open_was_deferred(req->xconn, req->mid)) {
6422                         /* We have re-scheduled this call. */
6423                         return;
6424                 }
6425                 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6426                         bool ok = defer_smb1_sharing_violation(req);
6427                         if (ok) {
6428                                 return;
6429                         }
6430                 }
6431                 reply_nterror(req, status);
6432                 return;
6433         }
6434         if (fixed_portion > max_data_bytes) {
6435                 reply_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH);
6436                 return;
6437         }
6438
6439         send_trans2_replies(conn, req, NT_STATUS_OK, params, param_size, *ppdata, data_size,
6440                             max_data_bytes);
6441
6442         return;
6443 }
6444
6445 /****************************************************************************
6446  Set a hard link (called by UNIX extensions and by NT rename with HARD link
6447  code.
6448 ****************************************************************************/
6449
6450 NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
6451                 connection_struct *conn,
6452                 struct smb_request *req,
6453                 bool overwrite_if_exists,
6454                 const struct smb_filename *smb_fname_old,
6455                 struct smb_filename *smb_fname_new)
6456 {
6457         NTSTATUS status = NT_STATUS_OK;
6458         int ret;
6459         bool ok;
6460
6461         /* source must already exist. */
6462         if (!VALID_STAT(smb_fname_old->st)) {
6463                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6464         }
6465
6466         if (VALID_STAT(smb_fname_new->st)) {
6467                 if (overwrite_if_exists) {
6468                         if (S_ISDIR(smb_fname_new->st.st_ex_mode)) {
6469                                 return NT_STATUS_FILE_IS_A_DIRECTORY;
6470                         }
6471                         status = unlink_internals(conn,
6472                                                 req,
6473                                                 FILE_ATTRIBUTE_NORMAL,
6474                                                 smb_fname_new,
6475                                                 false);
6476                         if (!NT_STATUS_IS_OK(status)) {
6477                                 return status;
6478                         }
6479                 } else {
6480                         /* Disallow if newname already exists. */
6481                         return NT_STATUS_OBJECT_NAME_COLLISION;
6482                 }
6483         }
6484
6485         /* No links from a directory. */
6486         if (S_ISDIR(smb_fname_old->st.st_ex_mode)) {
6487                 return NT_STATUS_FILE_IS_A_DIRECTORY;
6488         }
6489
6490         /* Setting a hardlink to/from a stream isn't currently supported. */
6491         ok = is_ntfs_stream_smb_fname(smb_fname_old);
6492         if (ok) {
6493                 DBG_DEBUG("Old name has streams\n");
6494                 return NT_STATUS_INVALID_PARAMETER;
6495         }
6496         ok = is_ntfs_stream_smb_fname(smb_fname_new);
6497         if (ok) {
6498                 DBG_DEBUG("New name has streams\n");
6499                 return NT_STATUS_INVALID_PARAMETER;
6500         }
6501
6502         DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
6503                   smb_fname_old->base_name, smb_fname_new->base_name));
6504
6505         ret = SMB_VFS_LINKAT(conn,
6506                         conn->cwd_fsp,
6507                         smb_fname_old,
6508                         conn->cwd_fsp,
6509                         smb_fname_new,
6510                         0);
6511
6512         if (ret != 0) {
6513                 status = map_nt_error_from_unix(errno);
6514                 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
6515                          nt_errstr(status), smb_fname_old->base_name,
6516                          smb_fname_new->base_name));
6517         }
6518         return status;
6519 }
6520
6521 /****************************************************************************
6522  Deal with setting the time from any of the setfilepathinfo functions.
6523  NOTE !!!! The check for FILE_WRITE_ATTRIBUTES access must be done *before*
6524  calling this function.
6525 ****************************************************************************/
6526
6527 NTSTATUS smb_set_file_time(connection_struct *conn,
6528                            files_struct *fsp,
6529                            const struct smb_filename *smb_fname,
6530                            struct smb_file_time *ft,
6531                            bool setting_write_time)
6532 {
6533         struct smb_filename smb_fname_base;
6534         struct timeval_buf tbuf[4];
6535         uint32_t action =
6536                 FILE_NOTIFY_CHANGE_LAST_ACCESS
6537                 |FILE_NOTIFY_CHANGE_LAST_WRITE
6538                 |FILE_NOTIFY_CHANGE_CREATION;
6539
6540         if (!VALID_STAT(smb_fname->st)) {
6541                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6542         }
6543
6544         /* get some defaults (no modifications) if any info is zero or -1. */
6545         if (is_omit_timespec(&ft->create_time)) {
6546                 action &= ~FILE_NOTIFY_CHANGE_CREATION;
6547         }
6548
6549         if (is_omit_timespec(&ft->atime)) {
6550                 action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
6551         }
6552
6553         if (is_omit_timespec(&ft->mtime)) {
6554                 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
6555         }
6556
6557         if (!setting_write_time) {
6558                 /* ft->mtime comes from change time, not write time. */
6559                 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
6560         }
6561
6562         /* Ensure the resolution is the correct for
6563          * what we can store on this filesystem. */
6564
6565         round_timespec(conn->ts_res, &ft->create_time);
6566         round_timespec(conn->ts_res, &ft->ctime);
6567         round_timespec(conn->ts_res, &ft->atime);
6568         round_timespec(conn->ts_res, &ft->mtime);
6569
6570         DBG_DEBUG("smb_set_filetime: actime: %s\n ",
6571                   timespec_string_buf(&ft->atime, true, &tbuf[0]));
6572         DBG_DEBUG("smb_set_filetime: modtime: %s\n ",
6573                   timespec_string_buf(&ft->mtime, true, &tbuf[1]));
6574         DBG_DEBUG("smb_set_filetime: ctime: %s\n ",
6575                   timespec_string_buf(&ft->ctime, true, &tbuf[2]));
6576         DBG_DEBUG("smb_set_file_time: createtime: %s\n ",
6577                   timespec_string_buf(&ft->create_time, true, &tbuf[3]));
6578
6579         if (setting_write_time) {
6580                 /*
6581                  * This was a Windows setfileinfo on an open file.
6582                  * NT does this a lot. We also need to 
6583                  * set the time here, as it can be read by 
6584                  * FindFirst/FindNext and with the patch for bug #2045
6585                  * in smbd/fileio.c it ensures that this timestamp is
6586                  * kept sticky even after a write. We save the request
6587                  * away and will set it on file close and after a write. JRA.
6588                  */
6589
6590                 DBG_DEBUG("setting pending modtime to %s\n",
6591                           timespec_string_buf(&ft->mtime, true, &tbuf[0]));
6592
6593                 if (fsp != NULL) {
6594                         if (fsp->base_fsp) {
6595                                 set_sticky_write_time_fsp(fsp->base_fsp,
6596                                                           ft->mtime);
6597                         } else {
6598                                 set_sticky_write_time_fsp(fsp, ft->mtime);
6599                         }
6600                 } else {
6601                         set_sticky_write_time_path(
6602                                 vfs_file_id_from_sbuf(conn, &smb_fname->st),
6603                                 ft->mtime);
6604                 }
6605         }
6606
6607         DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
6608
6609         /* Always call ntimes on the base, even if a stream was passed in. */
6610         smb_fname_base = *smb_fname;
6611         smb_fname_base.stream_name = NULL;
6612
6613         if(file_ntimes(conn, &smb_fname_base, ft)!=0) {
6614                 return map_nt_error_from_unix(errno);
6615         }
6616
6617         notify_fname(conn, NOTIFY_ACTION_MODIFIED, action,
6618                      smb_fname->base_name);
6619         return NT_STATUS_OK;
6620 }
6621
6622 /****************************************************************************
6623  Deal with setting the dosmode from any of the setfilepathinfo functions.
6624  NB. The check for FILE_WRITE_ATTRIBUTES access on this path must have been
6625  done before calling this function.
6626 ****************************************************************************/
6627
6628 static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
6629                                      const struct smb_filename *smb_fname,
6630                                      uint32_t dosmode)
6631 {
6632         struct smb_filename *smb_fname_base;
6633         NTSTATUS status;
6634
6635         if (!VALID_STAT(smb_fname->st)) {
6636                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6637         }
6638
6639         /* Always operate on the base_name, even if a stream was passed in. */
6640         smb_fname_base = synthetic_smb_fname(talloc_tos(),
6641                                         smb_fname->base_name,
6642                                         NULL,
6643                                         &smb_fname->st,
6644                                         smb_fname->twrp,
6645                                         smb_fname->flags);
6646         if (smb_fname_base == NULL) {
6647                 return NT_STATUS_NO_MEMORY;
6648         }
6649
6650         if (dosmode) {
6651                 if (S_ISDIR(smb_fname_base->st.st_ex_mode)) {
6652                         dosmode |= FILE_ATTRIBUTE_DIRECTORY;
6653                 } else {
6654                         dosmode &= ~FILE_ATTRIBUTE_DIRECTORY;
6655                 }
6656         }
6657
6658         DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode));
6659
6660         /* check the mode isn't different, before changing it */
6661         if ((dosmode != 0) && (dosmode != dos_mode(conn, smb_fname_base))) {
6662                 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
6663                           "0x%x\n", smb_fname_str_dbg(smb_fname_base),
6664                           (unsigned int)dosmode));
6665
6666                 if(file_set_dosmode(conn, smb_fname_base, dosmode, NULL,
6667                                     false)) {
6668                         DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
6669                                  "%s failed (%s)\n",
6670                                  smb_fname_str_dbg(smb_fname_base),
6671                                  strerror(errno)));
6672                         status = map_nt_error_from_unix(errno);
6673                         goto out;
6674                 }
6675         }
6676         status = NT_STATUS_OK;
6677  out:
6678         TALLOC_FREE(smb_fname_base);
6679         return status;
6680 }
6681
6682 /****************************************************************************
6683  Deal with setting the size from any of the setfilepathinfo functions.
6684 ****************************************************************************/
6685
6686 static NTSTATUS smb_set_file_size(connection_struct *conn,
6687                                   struct smb_request *req,
6688                                   files_struct *fsp,
6689                                   const struct smb_filename *smb_fname,
6690                                   const SMB_STRUCT_STAT *psbuf,
6691                                   off_t size,
6692                                   bool fail_after_createfile)
6693 {
6694         NTSTATUS status = NT_STATUS_OK;
6695         struct smb_filename *smb_fname_tmp = NULL;
6696         files_struct *new_fsp = NULL;
6697
6698         if (!VALID_STAT(*psbuf)) {
6699                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6700         }
6701
6702         DBG_INFO("size: %"PRIu64", file_size_stat=%"PRIu64"\n",
6703                  (uint64_t)size,
6704                  get_file_size_stat(psbuf));
6705
6706         if (size == get_file_size_stat(psbuf)) {
6707                 if (fsp == NULL) {
6708                         return NT_STATUS_OK;
6709                 }
6710                 if (!fsp->fsp_flags.modified) {
6711                         return NT_STATUS_OK;
6712                 }
6713                 trigger_write_time_update_immediate(fsp);
6714                 return NT_STATUS_OK;
6715         }
6716
6717         DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
6718                   smb_fname_str_dbg(smb_fname), (double)size));
6719
6720         if (fsp && fsp->fh->fd != -1) {
6721                 /* Handle based call. */
6722                 if (!(fsp->access_mask & FILE_WRITE_DATA)) {
6723                         return NT_STATUS_ACCESS_DENIED;
6724                 }
6725
6726                 if (vfs_set_filelen(fsp, size) == -1) {
6727                         return map_nt_error_from_unix(errno);
6728                 }
6729                 trigger_write_time_update_immediate(fsp);
6730                 return NT_STATUS_OK;
6731         }
6732
6733         smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
6734         if (smb_fname_tmp == NULL) {
6735                 return NT_STATUS_NO_MEMORY;
6736         }
6737
6738         smb_fname_tmp->st = *psbuf;
6739
6740         status = SMB_VFS_CREATE_FILE(
6741                 conn,                                   /* conn */
6742                 req,                                    /* req */
6743                 0,                                      /* root_dir_fid */
6744                 smb_fname_tmp,                          /* fname */
6745                 FILE_WRITE_DATA,                        /* access_mask */
6746                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
6747                     FILE_SHARE_DELETE),
6748                 FILE_OPEN,                              /* create_disposition*/
6749                 0,                                      /* create_options */
6750                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
6751                 0,                                      /* oplock_request */
6752                 NULL,                                   /* lease */
6753                 0,                                      /* allocation_size */
6754                 0,                                      /* private_flags */
6755                 NULL,                                   /* sd */
6756                 NULL,                                   /* ea_list */
6757                 &new_fsp,                               /* result */
6758                 NULL,                                   /* pinfo */
6759                 NULL, NULL);                            /* create context */
6760
6761         TALLOC_FREE(smb_fname_tmp);
6762
6763         if (!NT_STATUS_IS_OK(status)) {
6764                 /* NB. We check for open_was_deferred in the caller. */
6765                 return status;
6766         }
6767
6768         /* See RAW-SFILEINFO-END-OF-FILE */
6769         if (fail_after_createfile) {
6770                 close_file(req, new_fsp,NORMAL_CLOSE);
6771                 return NT_STATUS_INVALID_LEVEL;
6772         }
6773
6774         if (vfs_set_filelen(new_fsp, size) == -1) {
6775                 status = map_nt_error_from_unix(errno);
6776                 close_file(req, new_fsp,NORMAL_CLOSE);
6777                 return status;
6778         }
6779
6780         trigger_write_time_update_immediate(new_fsp);
6781         close_file(req, new_fsp,NORMAL_CLOSE);
6782         return NT_STATUS_OK;
6783 }
6784
6785 /****************************************************************************
6786  Deal with SMB_INFO_SET_EA.
6787 ****************************************************************************/
6788
6789 static NTSTATUS smb_info_set_ea(connection_struct *conn,
6790                                 const char *pdata,
6791                                 int total_data,
6792                                 files_struct *fsp,
6793                                 const struct smb_filename *smb_fname)
6794 {
6795         struct ea_list *ea_list = NULL;
6796         TALLOC_CTX *ctx = NULL;
6797         NTSTATUS status = NT_STATUS_OK;
6798
6799         if (total_data < 10) {
6800
6801                 /* OS/2 workplace shell seems to send SET_EA requests of "null"
6802                    length. They seem to have no effect. Bug #3212. JRA */
6803
6804                 if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
6805                         /* We're done. We only get EA info in this call. */
6806                         return NT_STATUS_OK;
6807                 }
6808
6809                 return NT_STATUS_INVALID_PARAMETER;
6810         }
6811
6812         if (IVAL(pdata,0) > total_data) {
6813                 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
6814                         IVAL(pdata,0), (unsigned int)total_data));
6815                 return NT_STATUS_INVALID_PARAMETER;
6816         }
6817
6818         ctx = talloc_tos();
6819         ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
6820         if (!ea_list) {
6821                 return NT_STATUS_INVALID_PARAMETER;
6822         }
6823
6824         status = set_ea(conn, fsp, smb_fname, ea_list);
6825
6826         return status;
6827 }
6828
6829 /****************************************************************************
6830  Deal with SMB_FILE_FULL_EA_INFORMATION set.
6831 ****************************************************************************/
6832
6833 static NTSTATUS smb_set_file_full_ea_info(connection_struct *conn,
6834                                 const char *pdata,
6835                                 int total_data,
6836                                 files_struct *fsp)
6837 {
6838         struct ea_list *ea_list = NULL;
6839         NTSTATUS status;
6840
6841         if (!fsp) {
6842                 return NT_STATUS_INVALID_HANDLE;
6843         }
6844
6845         if (!lp_ea_support(SNUM(conn))) {
6846                 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
6847                         "EA's not supported.\n",
6848                         (unsigned int)total_data));
6849                 return NT_STATUS_EAS_NOT_SUPPORTED;
6850         }
6851
6852         if (total_data < 10) {
6853                 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
6854                         "too small.\n",
6855                         (unsigned int)total_data));
6856                 return NT_STATUS_INVALID_PARAMETER;
6857         }
6858
6859         ea_list = read_nttrans_ea_list(talloc_tos(),
6860                                 pdata,
6861                                 total_data);
6862
6863         if (!ea_list) {
6864                 return NT_STATUS_INVALID_PARAMETER;
6865         }
6866
6867         status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
6868
6869         DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
6870                 smb_fname_str_dbg(fsp->fsp_name),
6871                 nt_errstr(status) ));
6872
6873         return status;
6874 }
6875
6876
6877 /****************************************************************************
6878  Deal with SMB_SET_FILE_DISPOSITION_INFO.
6879 ****************************************************************************/
6880
6881 static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
6882                                 const char *pdata,
6883                                 int total_data,
6884                                 files_struct *fsp,
6885                                 struct smb_filename *smb_fname)
6886 {
6887         NTSTATUS status = NT_STATUS_OK;
6888         bool delete_on_close;
6889         uint32_t dosmode = 0;
6890
6891         if (total_data < 1) {
6892                 return NT_STATUS_INVALID_PARAMETER;
6893         }
6894
6895         if (fsp == NULL) {
6896                 return NT_STATUS_INVALID_HANDLE;
6897         }
6898
6899         delete_on_close = (CVAL(pdata,0) ? True : False);
6900         dosmode = dos_mode(conn, smb_fname);
6901
6902         DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
6903                 "delete_on_close = %u\n",
6904                 smb_fname_str_dbg(smb_fname),
6905                 (unsigned int)dosmode,
6906                 (unsigned int)delete_on_close ));
6907
6908         if (delete_on_close) {
6909                 status = can_set_delete_on_close(fsp, dosmode);
6910                 if (!NT_STATUS_IS_OK(status)) {
6911                         return status;
6912                 }
6913         }
6914
6915         /* The set is across all open files on this dev/inode pair. */
6916         if (!set_delete_on_close(fsp, delete_on_close,
6917                                  conn->session_info->security_token,
6918                                  conn->session_info->unix_token)) {
6919                 return NT_STATUS_ACCESS_DENIED;
6920         }
6921         return NT_STATUS_OK;
6922 }
6923
6924 /****************************************************************************
6925  Deal with SMB_FILE_POSITION_INFORMATION.
6926 ****************************************************************************/
6927
6928 static NTSTATUS smb_file_position_information(connection_struct *conn,
6929                                 const char *pdata,
6930                                 int total_data,
6931                                 files_struct *fsp)
6932 {
6933         uint64_t position_information;
6934
6935         if (total_data < 8) {
6936                 return NT_STATUS_INVALID_PARAMETER;
6937         }
6938
6939         if (fsp == NULL) {
6940                 /* Ignore on pathname based set. */
6941                 return NT_STATUS_OK;
6942         }
6943
6944         position_information = (uint64_t)IVAL(pdata,0);
6945         position_information |= (((uint64_t)IVAL(pdata,4)) << 32);
6946
6947         DEBUG(10,("smb_file_position_information: Set file position "
6948                   "information for file %s to %.0f\n", fsp_str_dbg(fsp),
6949                   (double)position_information));
6950         fsp->fh->position_information = position_information;
6951         return NT_STATUS_OK;
6952 }
6953
6954 /****************************************************************************
6955  Deal with SMB_FILE_MODE_INFORMATION.
6956 ****************************************************************************/
6957
6958 static NTSTATUS smb_file_mode_information(connection_struct *conn,
6959                                 const char *pdata,
6960                                 int total_data)
6961 {
6962         uint32_t mode;
6963
6964         if (total_data < 4) {
6965                 return NT_STATUS_INVALID_PARAMETER;
6966         }
6967         mode = IVAL(pdata,0);
6968         if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
6969                 return NT_STATUS_INVALID_PARAMETER;
6970         }
6971         return NT_STATUS_OK;
6972 }
6973
6974 /****************************************************************************
6975  Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
6976 ****************************************************************************/
6977
6978 static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
6979                                        struct smb_request *req,
6980                                        const char *pdata,
6981                                        int total_data,
6982                                        const struct smb_filename *new_smb_fname)
6983 {
6984         char *link_target = NULL;
6985         struct smb_filename target_fname;
6986         TALLOC_CTX *ctx = talloc_tos();
6987         NTSTATUS status;
6988         int ret;
6989
6990         /* Set a symbolic link. */
6991         /* Don't allow this if follow links is false. */
6992
6993         if (total_data == 0) {
6994                 return NT_STATUS_INVALID_PARAMETER;
6995         }
6996
6997         if (!lp_follow_symlinks(SNUM(conn))) {
6998                 return NT_STATUS_ACCESS_DENIED;
6999         }
7000
7001         srvstr_pull_talloc(ctx, pdata, req->flags2, &link_target, pdata,
7002                     total_data, STR_TERMINATE);
7003
7004         if (!link_target) {
7005                 return NT_STATUS_INVALID_PARAMETER;
7006         }
7007
7008         target_fname = (struct smb_filename) {
7009                 .base_name = link_target,
7010         };
7011
7012         /* Removes @GMT tokens if any */
7013         status = canonicalize_snapshot_path(&target_fname, 0);
7014         if (!NT_STATUS_IS_OK(status)) {
7015                 return status;
7016         }
7017
7018         DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
7019                         new_smb_fname->base_name, link_target ));
7020
7021         ret = SMB_VFS_SYMLINKAT(conn,
7022                         &target_fname,
7023                         conn->cwd_fsp,
7024                         new_smb_fname);
7025         if (ret != 0) {
7026                 return map_nt_error_from_unix(errno);
7027         }
7028
7029         return NT_STATUS_OK;
7030 }
7031
7032 /****************************************************************************
7033  Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
7034 ****************************************************************************/
7035
7036 static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
7037                                         struct smb_request *req,
7038                                         const char *pdata, int total_data,
7039                                         struct smb_filename *smb_fname_new)
7040 {
7041         char *oldname = NULL;
7042         struct smb_filename *smb_fname_old = NULL;
7043         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
7044         TALLOC_CTX *ctx = talloc_tos();
7045         NTSTATUS status = NT_STATUS_OK;
7046
7047         /* Set a hard link. */
7048         if (total_data == 0) {
7049                 return NT_STATUS_INVALID_PARAMETER;
7050         }
7051
7052         if (req->posix_pathnames) {
7053                 srvstr_get_path_posix(ctx,
7054                         pdata,
7055                         req->flags2,
7056                         &oldname,
7057                         pdata,
7058                         total_data,
7059                         STR_TERMINATE,
7060                         &status);
7061         } else {
7062                 srvstr_get_path(ctx,
7063                         pdata,
7064                         req->flags2,
7065                         &oldname,
7066                         pdata,
7067                         total_data,
7068                         STR_TERMINATE,
7069                         &status);
7070         }
7071         if (!NT_STATUS_IS_OK(status)) {
7072                 return status;
7073         }
7074
7075         DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
7076                 smb_fname_str_dbg(smb_fname_new), oldname));
7077
7078         status = filename_convert(ctx,
7079                                 conn,
7080                                 oldname,
7081                                 ucf_flags,
7082                                 0,
7083                                 NULL,
7084                                 &smb_fname_old);
7085         if (!NT_STATUS_IS_OK(status)) {
7086                 return status;
7087         }
7088
7089         return hardlink_internals(ctx, conn, req, false,
7090                         smb_fname_old, smb_fname_new);
7091 }
7092
7093 /****************************************************************************
7094  Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
7095 ****************************************************************************/
7096
7097 static NTSTATUS smb2_file_rename_information(connection_struct *conn,
7098                                             struct smb_request *req,
7099                                             const char *pdata,
7100                                             int total_data,
7101                                             files_struct *fsp,
7102                                             struct smb_filename *smb_fname_src)
7103 {
7104         bool overwrite;
7105         uint32_t len;
7106         char *newname = NULL;
7107         struct smb_filename *smb_fname_dst = NULL;
7108         const char *dst_original_lcomp = NULL;
7109         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
7110         NTSTATUS status = NT_STATUS_OK;
7111         TALLOC_CTX *ctx = talloc_tos();
7112
7113         if (!fsp) {
7114                 return NT_STATUS_INVALID_HANDLE;
7115         }
7116
7117         if (total_data < 20) {
7118                 return NT_STATUS_INVALID_PARAMETER;
7119         }
7120
7121         overwrite = (CVAL(pdata,0) ? True : False);
7122         len = IVAL(pdata,16);
7123
7124         if (len > (total_data - 20) || (len == 0)) {
7125                 return NT_STATUS_INVALID_PARAMETER;
7126         }
7127
7128         if (req->posix_pathnames) {
7129                 srvstr_get_path_posix(ctx,
7130                                 pdata,
7131                                 req->flags2,
7132                                 &newname,
7133                                 &pdata[20],
7134                                 len,
7135                                 STR_TERMINATE,
7136                                 &status);
7137         } else {
7138                 srvstr_get_path(ctx,
7139                                 pdata,
7140                                 req->flags2,
7141                                 &newname,
7142                                 &pdata[20],
7143                                 len,
7144                                 STR_TERMINATE,
7145                                 &status);
7146         }
7147         if (!NT_STATUS_IS_OK(status)) {
7148                 return status;
7149         }
7150
7151         DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
7152                                 newname));
7153
7154         status = filename_convert(ctx,
7155                                 conn,
7156                                 newname,
7157                                 ucf_flags,
7158                                 0,
7159                                 NULL,
7160                                 &smb_fname_dst);
7161         if (!NT_STATUS_IS_OK(status)) {
7162                 return status;
7163         }
7164
7165         if (fsp->base_fsp) {
7166                 /* newname must be a stream name. */
7167                 if (newname[0] != ':') {
7168                         return NT_STATUS_NOT_SUPPORTED;
7169                 }
7170
7171                 /* Create an smb_fname to call rename_internals_fsp() with. */
7172                 smb_fname_dst = synthetic_smb_fname(talloc_tos(),
7173                                         fsp->base_fsp->fsp_name->base_name,
7174                                         newname,
7175                                         NULL,
7176                                         fsp->base_fsp->fsp_name->twrp,
7177                                         fsp->base_fsp->fsp_name->flags);
7178                 if (smb_fname_dst == NULL) {
7179                         status = NT_STATUS_NO_MEMORY;
7180                         goto out;
7181                 }
7182         }
7183
7184         /*
7185          * Set the original last component, since
7186          * rename_internals_fsp() requires it.
7187          */
7188         dst_original_lcomp = get_original_lcomp(smb_fname_dst,
7189                                         conn,
7190                                         newname,
7191                                         ucf_flags);
7192         if (dst_original_lcomp == NULL) {
7193                 status = NT_STATUS_NO_MEMORY;
7194                 goto out;
7195         }
7196
7197         DEBUG(10,("smb2_file_rename_information: "
7198                   "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
7199                   fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
7200                   smb_fname_str_dbg(smb_fname_dst)));
7201         status = rename_internals_fsp(conn,
7202                                 fsp,
7203                                 smb_fname_dst,
7204                                 dst_original_lcomp,
7205                                 (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM),
7206                                 overwrite);
7207
7208  out:
7209         TALLOC_FREE(smb_fname_dst);
7210         return status;
7211 }
7212
7213 static NTSTATUS smb_file_link_information(connection_struct *conn,
7214                                             struct smb_request *req,
7215                                             const char *pdata,
7216                                             int total_data,
7217                                             files_struct *fsp,
7218                                             struct smb_filename *smb_fname_src)
7219 {
7220         bool overwrite;
7221         uint32_t len;
7222         char *newname = NULL;
7223         struct smb_filename *smb_fname_dst = NULL;
7224         NTSTATUS status = NT_STATUS_OK;
7225         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
7226         TALLOC_CTX *ctx = talloc_tos();
7227
7228         if (!fsp) {
7229                 return NT_STATUS_INVALID_HANDLE;
7230         }
7231
7232         if (total_data < 20) {
7233                 return NT_STATUS_INVALID_PARAMETER;
7234         }
7235
7236         overwrite = (CVAL(pdata,0) ? true : false);
7237         len = IVAL(pdata,16);
7238
7239         if (len > (total_data - 20) || (len == 0)) {
7240                 return NT_STATUS_INVALID_PARAMETER;
7241         }
7242
7243         if (smb_fname_src->flags & SMB_FILENAME_POSIX_PATH) {
7244                 srvstr_get_path_posix(ctx,
7245                                 pdata,
7246                                 req->flags2,
7247                                 &newname,
7248                                 &pdata[20],
7249                                 len,
7250                                 STR_TERMINATE,
7251                                 &status);
7252                 ucf_flags |= UCF_POSIX_PATHNAMES;
7253         } else {
7254                 srvstr_get_path(ctx,
7255                                 pdata,
7256                                 req->flags2,
7257                                 &newname,
7258                                 &pdata[20],
7259                                 len,
7260                                 STR_TERMINATE,
7261                                 &status);
7262         }
7263         if (!NT_STATUS_IS_OK(status)) {
7264                 return status;
7265         }
7266
7267         DEBUG(10,("smb_file_link_information: got name |%s|\n",
7268                                 newname));
7269
7270         status = filename_convert(ctx,
7271                                 conn,
7272                                 newname,
7273                                 ucf_flags,
7274                                 0,
7275                                 NULL,
7276                                 &smb_fname_dst);
7277         if (!NT_STATUS_IS_OK(status)) {
7278                 return status;
7279         }
7280
7281         if (fsp->base_fsp) {
7282                 /* No stream names. */
7283                 return NT_STATUS_NOT_SUPPORTED;
7284         }
7285
7286         DEBUG(10,("smb_file_link_information: "
7287                   "SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
7288                   fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
7289                   smb_fname_str_dbg(smb_fname_dst)));
7290         status = hardlink_internals(ctx,
7291                                 conn,
7292                                 req,
7293                                 overwrite,
7294                                 fsp->fsp_name,
7295                                 smb_fname_dst);
7296
7297         TALLOC_FREE(smb_fname_dst);
7298         return status;
7299 }
7300
7301 /****************************************************************************
7302  Deal with SMB_FILE_RENAME_INFORMATION.
7303 ****************************************************************************/
7304
7305 static NTSTATUS smb_file_rename_information(connection_struct *conn,
7306                                             struct smb_request *req,
7307                                             const char *pdata,
7308                                             int total_data,
7309                                             files_struct *fsp,
7310                                             struct smb_filename *smb_fname_src)
7311 {
7312         bool overwrite;
7313         uint32_t root_fid;
7314         uint32_t len;
7315         char *newname = NULL;
7316         struct smb_filename *smb_fname_dst = NULL;
7317         const char *dst_original_lcomp = NULL;
7318         bool dest_has_wcard = False;
7319         NTSTATUS status = NT_STATUS_OK;
7320         char *p;
7321         TALLOC_CTX *ctx = talloc_tos();
7322
7323         if (total_data < 13) {
7324                 return NT_STATUS_INVALID_PARAMETER;
7325         }
7326
7327         overwrite = (CVAL(pdata,0) ? True : False);
7328         root_fid = IVAL(pdata,4);
7329         len = IVAL(pdata,8);
7330
7331         if (len > (total_data - 12) || (len == 0) || (root_fid != 0)) {
7332                 return NT_STATUS_INVALID_PARAMETER;
7333         }
7334
7335         if (req->posix_pathnames) {
7336                 srvstr_get_path_wcard_posix(ctx,
7337                                 pdata,
7338                                 req->flags2,
7339                                 &newname,
7340                                 &pdata[12],
7341                                 len,
7342                                 0,
7343                                 &status,
7344                                 &dest_has_wcard);
7345         } else {
7346                 srvstr_get_path_wcard(ctx,
7347                                 pdata,
7348                                 req->flags2,
7349                                 &newname,
7350                                 &pdata[12],
7351                                 len,
7352                                 0,
7353                                 &status,
7354                                 &dest_has_wcard);
7355         }
7356         if (!NT_STATUS_IS_OK(status)) {
7357                 return status;
7358         }
7359
7360         DEBUG(10,("smb_file_rename_information: got name |%s|\n",
7361                                 newname));
7362
7363         /* Check the new name has no '/' characters. */
7364         if (strchr_m(newname, '/')) {
7365                 return NT_STATUS_NOT_SUPPORTED;
7366         }
7367
7368         if (fsp && fsp->base_fsp) {
7369                 /* newname must be a stream name. */
7370                 if (newname[0] != ':') {
7371                         return NT_STATUS_NOT_SUPPORTED;
7372                 }
7373
7374                 /* Create an smb_fname to call rename_internals_fsp() with. */
7375                 smb_fname_dst = synthetic_smb_fname(talloc_tos(),
7376                                         fsp->base_fsp->fsp_name->base_name,
7377                                         newname,
7378                                         NULL,
7379                                         fsp->base_fsp->fsp_name->twrp,
7380                                         fsp->base_fsp->fsp_name->flags);
7381                 if (smb_fname_dst == NULL) {
7382                         status = NT_STATUS_NO_MEMORY;
7383                         goto out;
7384                 }
7385
7386                 /*
7387                  * Get the original last component, since
7388                  * rename_internals_fsp() requires it.
7389                  */
7390                 dst_original_lcomp = get_original_lcomp(smb_fname_dst,
7391                                         conn,
7392                                         newname,
7393                                         0);
7394                 if (dst_original_lcomp == NULL) {
7395                         status = NT_STATUS_NO_MEMORY;
7396                         goto out;
7397                 }
7398
7399         } else {
7400                 /*
7401                  * Build up an smb_fname_dst based on the filename passed in.
7402                  * We basically just strip off the last component, and put on
7403                  * the newname instead.
7404                  */
7405                 char *base_name = NULL;
7406                 uint32_t ucf_flags = ucf_flags_from_smb_request(req);
7407
7408                 if (dest_has_wcard) {
7409                         ucf_flags |= UCF_ALWAYS_ALLOW_WCARD_LCOMP;
7410                 }
7411
7412                 /* newname must *not* be a stream name. */
7413                 if (newname[0] == ':') {
7414                         return NT_STATUS_NOT_SUPPORTED;
7415                 }
7416
7417                 /*
7418                  * Strip off the last component (filename) of the path passed
7419                  * in.
7420                  */
7421                 base_name = talloc_strdup(ctx, smb_fname_src->base_name);
7422                 if (!base_name) {
7423                         return NT_STATUS_NO_MEMORY;
7424                 }
7425                 p = strrchr_m(base_name, '/');
7426                 if (p) {
7427                         p[1] = '\0';
7428                 } else {
7429                         base_name = talloc_strdup(ctx, "");
7430                         if (!base_name) {
7431                                 return NT_STATUS_NO_MEMORY;
7432                         }
7433                 }
7434                 /* Append the new name. */
7435                 base_name = talloc_asprintf_append(base_name,
7436                                 "%s",
7437                                 newname);
7438                 if (!base_name) {
7439                         return NT_STATUS_NO_MEMORY;
7440                 }
7441
7442                 status = filename_convert(ctx,
7443                                           conn,
7444                                           base_name,
7445                                           ucf_flags,
7446                                           0,
7447                                           NULL,
7448                                           &smb_fname_dst);
7449
7450                 /* If an error we expect this to be
7451                  * NT_STATUS_OBJECT_PATH_NOT_FOUND */
7452
7453                 if (!NT_STATUS_IS_OK(status)) {
7454                         if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND,
7455                                             status)) {
7456                                 goto out;
7457                         }
7458                         /* Create an smb_fname to call rename_internals_fsp() */
7459                         smb_fname_dst = synthetic_smb_fname(ctx,
7460                                                 base_name,
7461                                                 NULL,
7462                                                 NULL,
7463                                                 smb_fname_src->twrp,
7464                                                 smb_fname_src->flags);
7465                         if (smb_fname_dst == NULL) {
7466                                 status = NT_STATUS_NO_MEMORY;
7467                                 goto out;
7468                         }
7469                 }
7470                 dst_original_lcomp = get_original_lcomp(smb_fname_dst,
7471                                         conn,
7472                                         newname,
7473                                         ucf_flags);
7474                 if (dst_original_lcomp == NULL) {
7475                         status = NT_STATUS_NO_MEMORY;
7476                         goto out;
7477                 }
7478         }
7479
7480         if (fsp) {
7481                 DEBUG(10,("smb_file_rename_information: "
7482                           "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
7483                           fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
7484                           smb_fname_str_dbg(smb_fname_dst)));
7485                 status = rename_internals_fsp(conn,
7486                                         fsp,
7487                                         smb_fname_dst,
7488                                         dst_original_lcomp,
7489                                         0,
7490                                         overwrite);
7491         } else {
7492                 DEBUG(10,("smb_file_rename_information: "
7493                           "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
7494                           smb_fname_str_dbg(smb_fname_src),
7495                           smb_fname_str_dbg(smb_fname_dst)));
7496                 status = rename_internals(ctx,
7497                                         conn,
7498                                         req,
7499                                         smb_fname_src,
7500                                         smb_fname_dst,
7501                                         dst_original_lcomp,
7502                                         0,
7503                                         overwrite,
7504                                         false,
7505                                         dest_has_wcard,
7506                                         FILE_WRITE_ATTRIBUTES);
7507         }
7508  out:
7509         TALLOC_FREE(smb_fname_dst);
7510         return status;
7511 }
7512
7513 /****************************************************************************
7514  Deal with SMB_SET_POSIX_ACL.
7515 ****************************************************************************/
7516
7517 #if defined(HAVE_POSIX_ACLS)
7518 static NTSTATUS smb_set_posix_acl(connection_struct *conn,
7519                                 struct smb_request *req,
7520                                 const char *pdata,
7521                                 int total_data_in,
7522                                 files_struct *fsp,
7523                                 const struct smb_filename *smb_fname)
7524 {
7525         uint16_t posix_acl_version;
7526         uint16_t num_file_acls;
7527         uint16_t num_def_acls;
7528         bool valid_file_acls = true;
7529         bool valid_def_acls = true;
7530         NTSTATUS status;
7531         unsigned int size_needed;
7532         unsigned int total_data;
7533         bool close_fsp = false;
7534
7535         if (total_data_in < 0) {
7536                 status = NT_STATUS_INVALID_PARAMETER;
7537                 goto out;
7538         }
7539
7540         total_data = total_data_in;
7541
7542         if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
7543                 status = NT_STATUS_INVALID_PARAMETER;
7544                 goto out;
7545         }
7546         posix_acl_version = SVAL(pdata,0);
7547         num_file_acls = SVAL(pdata,2);
7548         num_def_acls = SVAL(pdata,4);
7549
7550         if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
7551                 valid_file_acls = false;
7552                 num_file_acls = 0;
7553         }
7554
7555         if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
7556                 valid_def_acls = false;
7557                 num_def_acls = 0;
7558         }
7559
7560         if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
7561                 status = NT_STATUS_INVALID_PARAMETER;
7562                 goto out;
7563         }
7564
7565         /* Wrap checks. */
7566         if (num_file_acls + num_def_acls < num_file_acls) {
7567                 status = NT_STATUS_INVALID_PARAMETER;
7568                 goto out;
7569         }
7570
7571         size_needed = num_file_acls + num_def_acls;
7572
7573         /*
7574          * (size_needed * SMB_POSIX_ACL_ENTRY_SIZE) must be less
7575          * than UINT_MAX, so check by division.
7576          */
7577         if (size_needed > (UINT_MAX/SMB_POSIX_ACL_ENTRY_SIZE)) {
7578                 status = NT_STATUS_INVALID_PARAMETER;
7579                 goto out;
7580         }
7581
7582         size_needed = size_needed*SMB_POSIX_ACL_ENTRY_SIZE;
7583         if (size_needed + SMB_POSIX_ACL_HEADER_SIZE < size_needed) {
7584                 status = NT_STATUS_INVALID_PARAMETER;
7585                 goto out;
7586         }
7587         size_needed += SMB_POSIX_ACL_HEADER_SIZE;
7588
7589         if (total_data < size_needed) {
7590                 status = NT_STATUS_INVALID_PARAMETER;
7591                 goto out;
7592         }
7593
7594         /*
7595          * Ensure we always operate on a file descriptor, not just
7596          * the filename.
7597          */
7598         if (fsp == NULL) {
7599                 uint32_t access_mask = SEC_STD_WRITE_OWNER|
7600                                         SEC_STD_WRITE_DAC|
7601                                         SEC_STD_READ_CONTROL|
7602                                         FILE_READ_ATTRIBUTES|
7603                                         FILE_WRITE_ATTRIBUTES;
7604
7605                 status = get_posix_fsp(conn,
7606                                         req,
7607                                         smb_fname,
7608                                         access_mask,
7609                                         &fsp);
7610
7611                 if (!NT_STATUS_IS_OK(status)) {
7612                         goto out;
7613                 }
7614                 close_fsp = true;
7615         }
7616
7617         /* Here we know fsp != NULL */
7618         SMB_ASSERT(fsp != NULL);
7619
7620         status = refuse_symlink(conn, fsp, fsp->fsp_name);
7621         if (!NT_STATUS_IS_OK(status)) {
7622                 goto out;
7623         }
7624
7625         /* If we have a default acl, this *must* be a directory. */
7626         if (valid_def_acls && !fsp->fsp_flags.is_directory) {
7627                 DBG_INFO("Can't set default acls on "
7628                          "non-directory %s\n",
7629                          fsp_str_dbg(fsp));
7630                 return NT_STATUS_INVALID_HANDLE;
7631         }
7632
7633         DBG_DEBUG("file %s num_file_acls = %"PRIu16", "
7634                   "num_def_acls = %"PRIu16"\n",
7635                   fsp_str_dbg(fsp),
7636                   num_file_acls,
7637                   num_def_acls);
7638
7639         /* Move pdata to the start of the file ACL entries. */
7640         pdata += SMB_POSIX_ACL_HEADER_SIZE;
7641
7642         if (valid_file_acls) {
7643                 status = set_unix_posix_acl(conn,
7644                                         fsp,
7645                                         num_file_acls,
7646                                         pdata);
7647                 if (!NT_STATUS_IS_OK(status)) {
7648                         goto out;
7649                 }
7650         }
7651
7652         /* Move pdata to the start of the default ACL entries. */
7653         pdata += (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE);
7654
7655         if (valid_def_acls) {
7656                 status = set_unix_posix_default_acl(conn,
7657                                         fsp,
7658                                         num_def_acls,
7659                                         pdata);
7660                 if (!NT_STATUS_IS_OK(status)) {
7661                         goto out;
7662                 }
7663         }
7664
7665         status = NT_STATUS_OK;
7666
7667   out:
7668
7669         if (close_fsp) {
7670                 (void)close_file(req, fsp, NORMAL_CLOSE);
7671                 fsp = NULL;
7672         }
7673         return status;
7674 }
7675 #endif
7676
7677 /****************************************************************************
7678  Deal with SMB_SET_POSIX_LOCK.
7679 ****************************************************************************/
7680
7681 static void smb_set_posix_lock_done(struct tevent_req *subreq);
7682
7683 static NTSTATUS smb_set_posix_lock(connection_struct *conn,
7684                                 struct smb_request *req,
7685                                 const char *pdata,
7686                                 int total_data,
7687                                 files_struct *fsp)
7688 {
7689         struct tevent_req *subreq = NULL;
7690         struct smbd_lock_element *lck = NULL;
7691         uint64_t count;
7692         uint64_t offset;
7693         uint64_t smblctx;
7694         bool blocking_lock = False;
7695         enum brl_type lock_type;
7696
7697         NTSTATUS status = NT_STATUS_OK;
7698
7699         if (fsp == NULL || fsp->fh->fd == -1) {
7700                 return NT_STATUS_INVALID_HANDLE;
7701         }
7702
7703         if (total_data != POSIX_LOCK_DATA_SIZE) {
7704                 return NT_STATUS_INVALID_PARAMETER;
7705         }
7706
7707         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
7708                 case POSIX_LOCK_TYPE_READ:
7709                         lock_type = READ_LOCK;
7710                         break;
7711                 case POSIX_LOCK_TYPE_WRITE:
7712                         /* Return the right POSIX-mappable error code for files opened read-only. */
7713                         if (!fsp->fsp_flags.can_write) {
7714                                 return NT_STATUS_INVALID_HANDLE;
7715                         }
7716                         lock_type = WRITE_LOCK;
7717                         break;
7718                 case POSIX_LOCK_TYPE_UNLOCK:
7719                         lock_type = UNLOCK_LOCK;
7720                         break;
7721                 default:
7722                         return NT_STATUS_INVALID_PARAMETER;
7723         }
7724
7725         switch (SVAL(pdata, POSIX_LOCK_FLAGS_OFFSET)) {
7726         case POSIX_LOCK_FLAG_NOWAIT:
7727                 blocking_lock = false;
7728                 break;
7729         case POSIX_LOCK_FLAG_WAIT:
7730                 blocking_lock = true;
7731                 break;
7732         default:
7733                 return NT_STATUS_INVALID_PARAMETER;
7734         }
7735
7736         if (!lp_blocking_locks(SNUM(conn))) { 
7737                 blocking_lock = False;
7738         }
7739
7740         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
7741         offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
7742                         ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
7743         count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
7744                         ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
7745
7746         DBG_DEBUG("file %s, lock_type = %u, smblctx = %"PRIu64", "
7747                   "count = %"PRIu64", offset = %"PRIu64"\n",
7748                   fsp_str_dbg(fsp),
7749                   (unsigned int)lock_type,
7750                   smblctx,
7751                   count,
7752                   offset);
7753
7754         if (lock_type == UNLOCK_LOCK) {
7755                 struct smbd_lock_element l = {
7756                         .req_guid = smbd_request_guid(req, 0),
7757                         .smblctx = smblctx,
7758                         .brltype = UNLOCK_LOCK,
7759                         .offset = offset,
7760                         .count = count,
7761                 };
7762                 status = smbd_do_unlocking(req, fsp, 1, &l, POSIX_LOCK);
7763                 return status;
7764         }
7765
7766         lck = talloc(req, struct smbd_lock_element);
7767         if (lck == NULL) {
7768                 return NT_STATUS_NO_MEMORY;
7769         }
7770
7771         *lck = (struct smbd_lock_element) {
7772                 .req_guid = smbd_request_guid(req, 0),
7773                 .smblctx = smblctx,
7774                 .brltype = lock_type,
7775                 .count = count,
7776                 .offset = offset,
7777         };
7778
7779         subreq = smbd_smb1_do_locks_send(
7780                 fsp,
7781                 req->sconn->ev_ctx,
7782                 &req,
7783                 fsp,
7784                 blocking_lock ? UINT32_MAX : 0,
7785                 true,           /* large_offset */
7786                 POSIX_LOCK,
7787                 1,
7788                 lck);
7789         if (subreq == NULL) {
7790                 TALLOC_FREE(lck);
7791                 return NT_STATUS_NO_MEMORY;
7792         }
7793         tevent_req_set_callback(subreq, smb_set_posix_lock_done, req);
7794         return NT_STATUS_EVENT_PENDING;
7795 }
7796
7797 static void smb_set_posix_lock_done(struct tevent_req *subreq)
7798 {
7799         struct smb_request *req = NULL;
7800         NTSTATUS status;
7801         bool ok;
7802
7803         ok = smbd_smb1_do_locks_extract_smbreq(subreq, talloc_tos(), &req);
7804         SMB_ASSERT(ok);
7805
7806         status = smbd_smb1_do_locks_recv(subreq);
7807         TALLOC_FREE(subreq);
7808
7809         if (NT_STATUS_IS_OK(status)) {
7810                 char params[2] = {0};
7811                 /* Fake up max_data_bytes here - we know it fits. */
7812                 send_trans2_replies(
7813                         req->conn,
7814                         req,
7815                         NT_STATUS_OK,
7816                         params,
7817                         2,
7818                         NULL,
7819                         0,
7820                         0xffff);
7821         } else {
7822                 reply_nterror(req, status);
7823                 ok = srv_send_smb(
7824                         req->xconn,
7825                         (char *)req->outbuf,
7826                         true,
7827                         req->seqnum+1,
7828                         IS_CONN_ENCRYPTED(req->conn),
7829                         NULL);
7830                 if (!ok) {
7831                         exit_server_cleanly("smb_set_posix_lock_done: "
7832                                             "srv_send_smb failed.");
7833                 }
7834         }
7835
7836         TALLOC_FREE(req);
7837         return;
7838 }
7839
7840 /****************************************************************************
7841  Deal with SMB_SET_FILE_BASIC_INFO.
7842 ****************************************************************************/
7843
7844 static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
7845                                         const char *pdata,
7846                                         int total_data,
7847                                         files_struct *fsp,
7848                                         const struct smb_filename *smb_fname)
7849 {
7850         /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
7851         struct smb_file_time ft;
7852         uint32_t dosmode = 0;
7853         NTSTATUS status = NT_STATUS_OK;
7854
7855         init_smb_file_time(&ft);
7856
7857         if (total_data < 36) {
7858                 return NT_STATUS_INVALID_PARAMETER;
7859         }
7860
7861         if (fsp != NULL) {
7862                 status = check_access_fsp(fsp, FILE_WRITE_ATTRIBUTES);
7863         } else {
7864                 status = check_access(conn,
7865                                 conn->cwd_fsp,
7866                                 smb_fname,
7867                                 FILE_WRITE_ATTRIBUTES);
7868         }
7869         if (!NT_STATUS_IS_OK(status)) {
7870                 return status;
7871         }
7872
7873         /* Set the attributes */
7874         dosmode = IVAL(pdata,32);
7875         status = smb_set_file_dosmode(conn, smb_fname, dosmode);
7876         if (!NT_STATUS_IS_OK(status)) {
7877                 return status;
7878         }
7879
7880         /* create time */
7881         ft.create_time = pull_long_date_full_timespec(pdata);
7882
7883         /* access time */
7884         ft.atime = pull_long_date_full_timespec(pdata+8);
7885
7886         /* write time. */
7887         ft.mtime = pull_long_date_full_timespec(pdata+16);
7888
7889         /* change time. */
7890         ft.ctime = pull_long_date_full_timespec(pdata+24);
7891
7892         DEBUG(10, ("smb_set_file_basic_info: file %s\n",
7893                    smb_fname_str_dbg(smb_fname)));
7894
7895         status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
7896         if (!NT_STATUS_IS_OK(status)) {
7897                 return status;
7898         }
7899
7900         if (fsp != NULL && fsp->fsp_flags.modified) {
7901                 trigger_write_time_update_immediate(fsp);
7902         }
7903         return NT_STATUS_OK;
7904 }
7905
7906 /****************************************************************************
7907  Deal with SMB_INFO_STANDARD.
7908 ****************************************************************************/
7909
7910 static NTSTATUS smb_set_info_standard(connection_struct *conn,
7911                                         const char *pdata,
7912                                         int total_data,
7913                                         files_struct *fsp,
7914                                         const struct smb_filename *smb_fname)
7915 {
7916         NTSTATUS status;
7917         struct smb_file_time ft;
7918
7919         init_smb_file_time(&ft);
7920
7921         if (total_data < 12) {
7922                 return NT_STATUS_INVALID_PARAMETER;
7923         }
7924
7925         /* create time */
7926         ft.create_time = time_t_to_full_timespec(srv_make_unix_date2(pdata));
7927         /* access time */
7928         ft.atime = time_t_to_full_timespec(srv_make_unix_date2(pdata+4));
7929         /* write time */
7930         ft.mtime = time_t_to_full_timespec(srv_make_unix_date2(pdata+8));
7931
7932         DEBUG(10,("smb_set_info_standard: file %s\n",
7933                 smb_fname_str_dbg(smb_fname)));
7934
7935         if (fsp != NULL) {
7936                 status = check_access_fsp(fsp, FILE_WRITE_ATTRIBUTES);
7937         } else {
7938                 status = check_access(conn,
7939                                 conn->cwd_fsp,
7940                                 smb_fname,
7941                                 FILE_WRITE_ATTRIBUTES);
7942         }
7943         if (!NT_STATUS_IS_OK(status)) {
7944                 return status;
7945         }
7946
7947         status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
7948         if (!NT_STATUS_IS_OK(status)) {
7949                 return status;
7950         }
7951
7952         if (fsp != NULL && fsp->fsp_flags.modified) {
7953                 trigger_write_time_update_immediate(fsp);
7954         }
7955         return NT_STATUS_OK;
7956 }
7957
7958 /****************************************************************************
7959  Deal with SMB_SET_FILE_ALLOCATION_INFO.
7960 ****************************************************************************/
7961
7962 static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
7963                                              struct smb_request *req,
7964                                         const char *pdata,
7965                                         int total_data,
7966                                         files_struct *fsp,
7967                                         struct smb_filename *smb_fname)
7968 {
7969         uint64_t allocation_size = 0;
7970         NTSTATUS status = NT_STATUS_OK;
7971         files_struct *new_fsp = NULL;
7972
7973         if (!VALID_STAT(smb_fname->st)) {
7974                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
7975         }
7976
7977         if (total_data < 8) {
7978                 return NT_STATUS_INVALID_PARAMETER;
7979         }
7980
7981         allocation_size = (uint64_t)IVAL(pdata,0);
7982         allocation_size |= (((uint64_t)IVAL(pdata,4)) << 32);
7983         DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
7984                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
7985                   (double)allocation_size));
7986
7987         if (allocation_size) {
7988                 allocation_size = smb_roundup(conn, allocation_size);
7989         }
7990
7991         DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
7992                   "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname),
7993                   (double)allocation_size));
7994
7995         if (fsp && fsp->fh->fd != -1) {
7996                 /* Open file handle. */
7997                 if (!(fsp->access_mask & FILE_WRITE_DATA)) {
7998                         return NT_STATUS_ACCESS_DENIED;
7999                 }
8000
8001                 /* Only change if needed. */
8002                 if (allocation_size != get_file_size_stat(&smb_fname->st)) {
8003                         if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
8004                                 return map_nt_error_from_unix(errno);
8005                         }
8006                 }
8007                 /* But always update the time. */
8008                 /*
8009                  * This is equivalent to a write. Ensure it's seen immediately
8010                  * if there are no pending writes.
8011                  */
8012                 trigger_write_time_update_immediate(fsp);
8013                 return NT_STATUS_OK;
8014         }
8015
8016         /* Pathname or stat or directory file. */
8017         status = SMB_VFS_CREATE_FILE(
8018                 conn,                                   /* conn */
8019                 req,                                    /* req */
8020                 0,                                      /* root_dir_fid */
8021                 smb_fname,                              /* fname */
8022                 FILE_WRITE_DATA,                        /* access_mask */
8023                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
8024                     FILE_SHARE_DELETE),
8025                 FILE_OPEN,                              /* create_disposition*/
8026                 0,                                      /* create_options */
8027                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
8028                 0,                                      /* oplock_request */
8029                 NULL,                                   /* lease */
8030                 0,                                      /* allocation_size */
8031                 0,                                      /* private_flags */
8032                 NULL,                                   /* sd */
8033                 NULL,                                   /* ea_list */
8034                 &new_fsp,                               /* result */
8035                 NULL,                                   /* pinfo */
8036                 NULL, NULL);                            /* create context */
8037
8038         if (!NT_STATUS_IS_OK(status)) {
8039                 /* NB. We check for open_was_deferred in the caller. */
8040                 return status;
8041         }
8042
8043         /* Only change if needed. */
8044         if (allocation_size != get_file_size_stat(&smb_fname->st)) {
8045                 if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
8046                         status = map_nt_error_from_unix(errno);
8047                         close_file(req, new_fsp, NORMAL_CLOSE);
8048                         return status;
8049                 }
8050         }
8051
8052         /* Changing the allocation size should set the last mod time. */
8053         /*
8054          * This is equivalent to a write. Ensure it's seen immediately
8055          * if there are no pending writes.
8056          */
8057         trigger_write_time_update_immediate(new_fsp);
8058         close_file(req, new_fsp, NORMAL_CLOSE);
8059         return NT_STATUS_OK;
8060 }
8061
8062 /****************************************************************************
8063  Deal with SMB_SET_FILE_END_OF_FILE_INFO.
8064 ****************************************************************************/
8065
8066 static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
8067                                               struct smb_request *req,
8068                                         const char *pdata,
8069                                         int total_data,
8070                                         files_struct *fsp,
8071                                         const struct smb_filename *smb_fname,
8072                                         bool fail_after_createfile)
8073 {
8074         off_t size;
8075
8076         if (total_data < 8) {
8077                 return NT_STATUS_INVALID_PARAMETER;
8078         }
8079
8080         size = IVAL(pdata,0);
8081         size |= (((off_t)IVAL(pdata,4)) << 32);
8082         DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
8083                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
8084                   (double)size));
8085
8086         return smb_set_file_size(conn, req,
8087                                 fsp,
8088                                 smb_fname,
8089                                 &smb_fname->st,
8090                                 size,
8091                                 fail_after_createfile);
8092 }
8093
8094 /****************************************************************************
8095  Allow a UNIX info mknod.
8096 ****************************************************************************/
8097
8098 static NTSTATUS smb_unix_mknod(connection_struct *conn,
8099                                         const char *pdata,
8100                                         int total_data,
8101                                         const struct smb_filename *smb_fname)
8102 {
8103         uint32_t file_type = IVAL(pdata,56);
8104 #if defined(HAVE_MAKEDEV)
8105         uint32_t dev_major = IVAL(pdata,60);
8106         uint32_t dev_minor = IVAL(pdata,68);
8107 #endif
8108         SMB_DEV_T dev = (SMB_DEV_T)0;
8109         uint32_t raw_unixmode = IVAL(pdata,84);
8110         NTSTATUS status;
8111         mode_t unixmode;
8112         int ret;
8113
8114         if (total_data < 100) {
8115                 return NT_STATUS_INVALID_PARAMETER;
8116         }
8117
8118         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8119                                       PERM_NEW_FILE, &unixmode);
8120         if (!NT_STATUS_IS_OK(status)) {
8121                 return status;
8122         }
8123
8124 #if defined(HAVE_MAKEDEV)
8125         dev = makedev(dev_major, dev_minor);
8126 #endif
8127
8128         switch (file_type) {
8129                 /* We can't create other objects here. */
8130                 case UNIX_TYPE_FILE:
8131                 case UNIX_TYPE_DIR:
8132                 case UNIX_TYPE_SYMLINK:
8133                         return NT_STATUS_ACCESS_DENIED;
8134 #if defined(S_IFIFO)
8135                 case UNIX_TYPE_FIFO:
8136                         unixmode |= S_IFIFO;
8137                         break;
8138 #endif
8139 #if defined(S_IFSOCK)
8140                 case UNIX_TYPE_SOCKET:
8141                         unixmode |= S_IFSOCK;
8142                         break;
8143 #endif
8144 #if defined(S_IFCHR)
8145                 case UNIX_TYPE_CHARDEV:
8146                         /* This is only allowed for root. */
8147                         if (get_current_uid(conn) != sec_initial_uid()) {
8148                                 return NT_STATUS_ACCESS_DENIED;
8149                         }
8150                         unixmode |= S_IFCHR;
8151                         break;
8152 #endif
8153 #if defined(S_IFBLK)
8154                 case UNIX_TYPE_BLKDEV:
8155                         if (get_current_uid(conn) != sec_initial_uid()) {
8156                                 return NT_STATUS_ACCESS_DENIED;
8157                         }
8158                         unixmode |= S_IFBLK;
8159                         break;
8160 #endif
8161                 default:
8162                         return NT_STATUS_INVALID_PARAMETER;
8163         }
8164
8165         DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
8166                   "%.0f mode 0%o for file %s\n", (double)dev,
8167                   (unsigned int)unixmode, smb_fname_str_dbg(smb_fname)));
8168
8169         /* Ok - do the mknod. */
8170         ret = SMB_VFS_MKNODAT(conn,
8171                         conn->cwd_fsp,
8172                         smb_fname,
8173                         unixmode,
8174                         dev);
8175
8176         if (ret != 0) {
8177                 return map_nt_error_from_unix(errno);
8178         }
8179
8180         /* If any of the other "set" calls fail we
8181          * don't want to end up with a half-constructed mknod.
8182          */
8183
8184         if (lp_inherit_permissions(SNUM(conn))) {
8185                 struct smb_filename *parent_fname = NULL;
8186                 bool ok;
8187
8188                 ok = parent_smb_fname(talloc_tos(),
8189                                       smb_fname,
8190                                       &parent_fname,
8191                                       NULL);
8192                 if (!ok) {
8193                         return NT_STATUS_NO_MEMORY;
8194                 }
8195                 inherit_access_posix_acl(conn,
8196                                          parent_fname,
8197                                          smb_fname,
8198                                          unixmode);
8199                 TALLOC_FREE(parent_fname);
8200         }
8201
8202         return NT_STATUS_OK;
8203 }
8204
8205 /****************************************************************************
8206  Deal with SMB_SET_FILE_UNIX_BASIC.
8207 ****************************************************************************/
8208
8209 static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
8210                                         struct smb_request *req,
8211                                         const char *pdata,
8212                                         int total_data,
8213                                         files_struct *fsp,
8214                                         const struct smb_filename *smb_fname)
8215 {
8216         struct smb_file_time ft;
8217         uint32_t raw_unixmode;
8218         mode_t unixmode;
8219         off_t size = 0;
8220         uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
8221         gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
8222         NTSTATUS status = NT_STATUS_OK;
8223         enum perm_type ptype;
8224         files_struct *all_fsps = NULL;
8225         bool modify_mtime = true;
8226         struct file_id id;
8227         SMB_STRUCT_STAT sbuf;
8228
8229         init_smb_file_time(&ft);
8230
8231         if (total_data < 100) {
8232                 return NT_STATUS_INVALID_PARAMETER;
8233         }
8234
8235         if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
8236            IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
8237                 size=IVAL(pdata,0); /* first 8 Bytes are size */
8238                 size |= (((off_t)IVAL(pdata,4)) << 32);
8239         }
8240
8241         ft.atime = pull_long_date_full_timespec(pdata+24); /* access_time */
8242         ft.mtime = pull_long_date_full_timespec(pdata+32); /* modification_time */
8243         set_owner = (uid_t)IVAL(pdata,40);
8244         set_grp = (gid_t)IVAL(pdata,48);
8245         raw_unixmode = IVAL(pdata,84);
8246
8247         if (VALID_STAT(smb_fname->st)) {
8248                 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
8249                         ptype = PERM_EXISTING_DIR;
8250                 } else {
8251                         ptype = PERM_EXISTING_FILE;
8252                 }
8253         } else {
8254                 ptype = PERM_NEW_FILE;
8255         }
8256
8257         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8258                                       ptype, &unixmode);
8259         if (!NT_STATUS_IS_OK(status)) {
8260                 return status;
8261         }
8262
8263         DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
8264                   "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
8265                   smb_fname_str_dbg(smb_fname), (double)size,
8266                   (unsigned int)set_owner, (unsigned int)set_grp,
8267                   (int)raw_unixmode));
8268
8269         sbuf = smb_fname->st;
8270
8271         if (!VALID_STAT(sbuf)) {
8272                 /*
8273                  * The only valid use of this is to create character and block
8274                  * devices, and named pipes. This is deprecated (IMHO) and 
8275                  * a new info level should be used for mknod. JRA.
8276                  */
8277
8278                 return smb_unix_mknod(conn,
8279                                         pdata,
8280                                         total_data,
8281                                         smb_fname);
8282         }
8283
8284 #if 1
8285         /* Horrible backwards compatibility hack as an old server bug
8286          * allowed a CIFS client bug to remain unnoticed :-(. JRA.
8287          * */
8288
8289         if (!size) {
8290                 size = get_file_size_stat(&sbuf);
8291         }
8292 #endif
8293
8294         /*
8295          * Deal with the UNIX specific mode set.
8296          */
8297
8298         if (raw_unixmode != SMB_MODE_NO_CHANGE) {
8299                 int ret;
8300
8301                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
8302                           "setting mode 0%o for file %s\n",
8303                           (unsigned int)unixmode,
8304                           smb_fname_str_dbg(smb_fname)));
8305                 if (fsp && fsp->fh->fd != -1) {
8306                         ret = SMB_VFS_FCHMOD(fsp, unixmode);
8307                 } else {
8308                         ret = SMB_VFS_CHMOD(conn, smb_fname, unixmode);
8309                 }
8310                 if (ret != 0) {
8311                         return map_nt_error_from_unix(errno);
8312                 }
8313         }
8314
8315         /*
8316          * Deal with the UNIX specific uid set.
8317          */
8318
8319         if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) &&
8320             (sbuf.st_ex_uid != set_owner)) {
8321                 int ret;
8322
8323                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
8324                           "changing owner %u for path %s\n",
8325                           (unsigned int)set_owner,
8326                           smb_fname_str_dbg(smb_fname)));
8327
8328                 if (fsp && fsp->fh->fd != -1) {
8329                         ret = SMB_VFS_FCHOWN(fsp, set_owner, (gid_t)-1);
8330                 } else {
8331                         /*
8332                          * UNIX extensions calls must always operate
8333                          * on symlinks.
8334                          */
8335                         ret = SMB_VFS_LCHOWN(conn, smb_fname,
8336                                              set_owner, (gid_t)-1);
8337                 }
8338
8339                 if (ret != 0) {
8340                         status = map_nt_error_from_unix(errno);
8341                         return status;
8342                 }
8343         }
8344
8345         /*
8346          * Deal with the UNIX specific gid set.
8347          */
8348
8349         if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) &&
8350             (sbuf.st_ex_gid != set_grp)) {
8351                 int ret;
8352
8353                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
8354                           "changing group %u for file %s\n",
8355                           (unsigned int)set_grp,
8356                           smb_fname_str_dbg(smb_fname)));
8357                 if (fsp && fsp->fh->fd != -1) {
8358                         ret = SMB_VFS_FCHOWN(fsp, (uid_t)-1, set_grp);
8359                 } else {
8360                         /*
8361                          * UNIX extensions calls must always operate
8362                          * on symlinks.
8363                          */
8364                         ret = SMB_VFS_LCHOWN(conn, smb_fname, (uid_t)-1,
8365                                   set_grp);
8366                 }
8367                 if (ret != 0) {
8368                         status = map_nt_error_from_unix(errno);
8369                         return status;
8370                 }
8371         }
8372
8373         /* Deal with any size changes. */
8374
8375         if (S_ISREG(sbuf.st_ex_mode)) {
8376                 status = smb_set_file_size(conn, req,
8377                                            fsp,
8378                                            smb_fname,
8379                                            &sbuf,
8380                                            size,
8381                                            false);
8382                 if (!NT_STATUS_IS_OK(status)) {
8383                         return status;
8384                 }
8385         }
8386
8387         /* Deal with any time changes. */
8388         if (is_omit_timespec(&ft.mtime) && is_omit_timespec(&ft.atime)) {
8389                 /* No change, don't cancel anything. */
8390                 return status;
8391         }
8392
8393         id = vfs_file_id_from_sbuf(conn, &sbuf);
8394         for(all_fsps = file_find_di_first(conn->sconn, id); all_fsps;
8395                         all_fsps = file_find_di_next(all_fsps)) {
8396                 /*
8397                  * We're setting the time explicitly for UNIX.
8398                  * Cancel any pending changes over all handles.
8399                  */
8400                 all_fsps->fsp_flags.update_write_time_on_close = false;
8401                 TALLOC_FREE(all_fsps->update_write_time_event);
8402         }
8403
8404         /*
8405          * Override the "setting_write_time"
8406          * parameter here as it almost does what
8407          * we need. Just remember if we modified
8408          * mtime and send the notify ourselves.
8409          */
8410         if (is_omit_timespec(&ft.mtime)) {
8411                 modify_mtime = false;
8412         }
8413
8414         status = smb_set_file_time(conn,
8415                                 fsp,
8416                                 smb_fname,
8417                                 &ft,
8418                                 false);
8419         if (modify_mtime) {
8420                 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
8421                         FILE_NOTIFY_CHANGE_LAST_WRITE, smb_fname->base_name);
8422         }
8423         return status;
8424 }
8425
8426 /****************************************************************************
8427  Deal with SMB_SET_FILE_UNIX_INFO2.
8428 ****************************************************************************/
8429
8430 static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
8431                                         struct smb_request *req,
8432                                         const char *pdata,
8433                                         int total_data,
8434                                         files_struct *fsp,
8435                                         const struct smb_filename *smb_fname)
8436 {
8437         NTSTATUS status;
8438         uint32_t smb_fflags;
8439         uint32_t smb_fmask;
8440
8441         if (total_data < 116) {
8442                 return NT_STATUS_INVALID_PARAMETER;
8443         }
8444
8445         /* Start by setting all the fields that are common between UNIX_BASIC
8446          * and UNIX_INFO2.
8447          */
8448         status = smb_set_file_unix_basic(conn, req, pdata, total_data,
8449                                          fsp, smb_fname);
8450         if (!NT_STATUS_IS_OK(status)) {
8451                 return status;
8452         }
8453
8454         smb_fflags = IVAL(pdata, 108);
8455         smb_fmask = IVAL(pdata, 112);
8456
8457         /* NB: We should only attempt to alter the file flags if the client
8458          * sends a non-zero mask.
8459          */
8460         if (smb_fmask != 0) {
8461                 int stat_fflags = 0;
8462
8463                 if (!map_info2_flags_to_sbuf(&smb_fname->st, smb_fflags,
8464                                              smb_fmask, &stat_fflags)) {
8465                         /* Client asked to alter a flag we don't understand. */
8466                         return NT_STATUS_INVALID_PARAMETER;
8467                 }
8468
8469                 if (fsp && fsp->fh->fd != -1) {
8470                         /* XXX: we should be  using SMB_VFS_FCHFLAGS here. */
8471                         return NT_STATUS_NOT_SUPPORTED;
8472                 } else {
8473                         if (SMB_VFS_CHFLAGS(conn, smb_fname,
8474                                             stat_fflags) != 0) {
8475                                 return map_nt_error_from_unix(errno);
8476                         }
8477                 }
8478         }
8479
8480         /* XXX: need to add support for changing the create_time here. You
8481          * can do this for paths on Darwin with setattrlist(2). The right way
8482          * to hook this up is probably by extending the VFS utimes interface.
8483          */
8484
8485         return NT_STATUS_OK;
8486 }
8487
8488 /****************************************************************************
8489  Create a directory with POSIX semantics.
8490 ****************************************************************************/
8491
8492 static NTSTATUS smb_posix_mkdir(connection_struct *conn,
8493                                 struct smb_request *req,
8494                                 char **ppdata,
8495                                 int total_data,
8496                                 struct smb_filename *smb_fname,
8497                                 int *pdata_return_size)
8498 {
8499         NTSTATUS status = NT_STATUS_OK;
8500         uint32_t raw_unixmode = 0;
8501         mode_t unixmode = (mode_t)0;
8502         files_struct *fsp = NULL;
8503         uint16_t info_level_return = 0;
8504         int info;
8505         char *pdata = *ppdata;
8506         struct smb2_create_blobs *posx = NULL;
8507
8508         if (total_data < 18) {
8509                 return NT_STATUS_INVALID_PARAMETER;
8510         }
8511
8512         raw_unixmode = IVAL(pdata,8);
8513         /* Next 4 bytes are not yet defined. */
8514
8515         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8516                                       PERM_NEW_DIR, &unixmode);
8517         if (!NT_STATUS_IS_OK(status)) {
8518                 return status;
8519         }
8520
8521         status = make_smb2_posix_create_ctx(talloc_tos(), &posx, unixmode);
8522         if (!NT_STATUS_IS_OK(status)) {
8523                 DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
8524                             nt_errstr(status));
8525                 return status;
8526         }
8527
8528         DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
8529                   smb_fname_str_dbg(smb_fname), (unsigned int)unixmode));
8530
8531         status = SMB_VFS_CREATE_FILE(
8532                 conn,                                   /* conn */
8533                 req,                                    /* req */
8534                 0,                                      /* root_dir_fid */
8535                 smb_fname,                              /* fname */
8536                 FILE_READ_ATTRIBUTES,                   /* access_mask */
8537                 FILE_SHARE_NONE,                        /* share_access */
8538                 FILE_CREATE,                            /* create_disposition*/
8539                 FILE_DIRECTORY_FILE,                    /* create_options */
8540                 0,                                      /* file_attributes */
8541                 0,                                      /* oplock_request */
8542                 NULL,                                   /* lease */
8543                 0,                                      /* allocation_size */
8544                 0,                                      /* private_flags */
8545                 NULL,                                   /* sd */
8546                 NULL,                                   /* ea_list */
8547                 &fsp,                                   /* result */
8548                 &info,                                  /* pinfo */
8549                 posx,                                   /* in_context_blobs */
8550                 NULL);                                  /* out_context_blobs */
8551
8552         TALLOC_FREE(posx);
8553
8554         if (NT_STATUS_IS_OK(status)) {
8555                 close_file(req, fsp, NORMAL_CLOSE);
8556         }
8557
8558         info_level_return = SVAL(pdata,16);
8559  
8560         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
8561                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
8562         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
8563                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
8564         } else {
8565                 *pdata_return_size = 12;
8566         }
8567
8568         /* Realloc the data size */
8569         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
8570         if (*ppdata == NULL) {
8571                 *pdata_return_size = 0;
8572                 return NT_STATUS_NO_MEMORY;
8573         }
8574         pdata = *ppdata;
8575
8576         SSVAL(pdata,0,NO_OPLOCK_RETURN);
8577         SSVAL(pdata,2,0); /* No fnum. */
8578         SIVAL(pdata,4,info); /* Was directory created. */
8579
8580         switch (info_level_return) {
8581                 case SMB_QUERY_FILE_UNIX_BASIC:
8582                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
8583                         SSVAL(pdata,10,0); /* Padding. */
8584                         store_file_unix_basic(conn, pdata + 12, fsp,
8585                                               &smb_fname->st);
8586                         break;
8587                 case SMB_QUERY_FILE_UNIX_INFO2:
8588                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
8589                         SSVAL(pdata,10,0); /* Padding. */
8590                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
8591                                                     &smb_fname->st);
8592                         break;
8593                 default:
8594                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
8595                         SSVAL(pdata,10,0); /* Padding. */
8596                         break;
8597         }
8598
8599         return status;
8600 }
8601
8602 /****************************************************************************
8603  Open/Create a file with POSIX semantics.
8604 ****************************************************************************/
8605
8606 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
8607 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
8608
8609 static NTSTATUS smb_posix_open(connection_struct *conn,
8610                                struct smb_request *req,
8611                                 char **ppdata,
8612                                 int total_data,
8613                                 struct smb_filename *smb_fname,
8614                                 int *pdata_return_size)
8615 {
8616         bool extended_oplock_granted = False;
8617         char *pdata = *ppdata;
8618         uint32_t flags = 0;
8619         uint32_t wire_open_mode = 0;
8620         uint32_t raw_unixmode = 0;
8621         uint32_t attributes = 0;
8622         uint32_t create_disp = 0;
8623         uint32_t access_mask = 0;
8624         uint32_t create_options = FILE_NON_DIRECTORY_FILE;
8625         NTSTATUS status = NT_STATUS_OK;
8626         mode_t unixmode = (mode_t)0;
8627         files_struct *fsp = NULL;
8628         int oplock_request = 0;
8629         int info = 0;
8630         uint16_t info_level_return = 0;
8631         struct smb2_create_blobs *posx = NULL;
8632
8633         if (total_data < 18) {
8634                 return NT_STATUS_INVALID_PARAMETER;
8635         }
8636
8637         flags = IVAL(pdata,0);
8638         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
8639         if (oplock_request) {
8640                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
8641         }
8642
8643         wire_open_mode = IVAL(pdata,4);
8644
8645         if (wire_open_mode == (SMB_O_CREAT|SMB_O_DIRECTORY)) {
8646                 return smb_posix_mkdir(conn, req,
8647                                         ppdata,
8648                                         total_data,
8649                                         smb_fname,
8650                                         pdata_return_size);
8651         }
8652
8653         switch (wire_open_mode & SMB_ACCMODE) {
8654                 case SMB_O_RDONLY:
8655                         access_mask = SMB_O_RDONLY_MAPPING;
8656                         break;
8657                 case SMB_O_WRONLY:
8658                         access_mask = SMB_O_WRONLY_MAPPING;
8659                         break;
8660                 case SMB_O_RDWR:
8661                         access_mask = (SMB_O_RDONLY_MAPPING|
8662                                         SMB_O_WRONLY_MAPPING);
8663                         break;
8664                 default:
8665                         DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
8666                                 (unsigned int)wire_open_mode ));
8667                         return NT_STATUS_INVALID_PARAMETER;
8668         }
8669
8670         wire_open_mode &= ~SMB_ACCMODE;
8671
8672         /* First take care of O_CREAT|O_EXCL interactions. */
8673         switch (wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) {
8674                 case (SMB_O_CREAT | SMB_O_EXCL):
8675                         /* File exists fail. File not exist create. */
8676                         create_disp = FILE_CREATE;
8677                         break;
8678                 case SMB_O_CREAT:
8679                         /* File exists open. File not exist create. */
8680                         create_disp = FILE_OPEN_IF;
8681                         break;
8682                 case SMB_O_EXCL:
8683                         /* O_EXCL on its own without O_CREAT is undefined.
8684                            We deliberately ignore it as some versions of
8685                            Linux CIFSFS can send a bare O_EXCL on the
8686                            wire which other filesystems in the kernel
8687                            ignore. See bug 9519 for details. */
8688
8689                         /* Fallthrough. */
8690
8691                 case 0:
8692                         /* File exists open. File not exist fail. */
8693                         create_disp = FILE_OPEN;
8694                         break;
8695                 default:
8696                         DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
8697                                 (unsigned int)wire_open_mode ));
8698                         return NT_STATUS_INVALID_PARAMETER;
8699         }
8700
8701         /* Next factor in the effects of O_TRUNC. */
8702         wire_open_mode &= ~(SMB_O_CREAT | SMB_O_EXCL);
8703
8704         if (wire_open_mode & SMB_O_TRUNC) {
8705                 switch (create_disp) {
8706                         case FILE_CREATE:
8707                                 /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
8708                                 /* Leave create_disp alone as
8709                                    (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
8710                                 */
8711                                 /* File exists fail. File not exist create. */
8712                                 break;
8713                         case FILE_OPEN_IF:
8714                                 /* SMB_O_CREAT | SMB_O_TRUNC */
8715                                 /* File exists overwrite. File not exist create. */
8716                                 create_disp = FILE_OVERWRITE_IF;
8717                                 break;
8718                         case FILE_OPEN:
8719                                 /* SMB_O_TRUNC */
8720                                 /* File exists overwrite. File not exist fail. */
8721                                 create_disp = FILE_OVERWRITE;
8722                                 break;
8723                         default:
8724                                 /* Cannot get here. */
8725                                 smb_panic("smb_posix_open: logic error");
8726                                 return NT_STATUS_INVALID_PARAMETER;
8727                 }
8728         }
8729
8730         raw_unixmode = IVAL(pdata,8);
8731         /* Next 4 bytes are not yet defined. */
8732
8733         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8734                                       (VALID_STAT(smb_fname->st) ?
8735                                           PERM_EXISTING_FILE : PERM_NEW_FILE),
8736                                       &unixmode);
8737
8738         if (!NT_STATUS_IS_OK(status)) {
8739                 return status;
8740         }
8741
8742         status = make_smb2_posix_create_ctx(talloc_tos(), &posx, unixmode);
8743         if (!NT_STATUS_IS_OK(status)) {
8744                 DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
8745                             nt_errstr(status));
8746                 return status;
8747         }
8748
8749         if (wire_open_mode & SMB_O_SYNC) {
8750                 create_options |= FILE_WRITE_THROUGH;
8751         }
8752         if (wire_open_mode & SMB_O_APPEND) {
8753                 access_mask |= FILE_APPEND_DATA;
8754         }
8755         if (wire_open_mode & SMB_O_DIRECT) {
8756                 attributes |= FILE_FLAG_NO_BUFFERING;
8757         }
8758
8759         if ((wire_open_mode & SMB_O_DIRECTORY) ||
8760                         VALID_STAT_OF_DIR(smb_fname->st)) {
8761                 if (access_mask != SMB_O_RDONLY_MAPPING) {
8762                         return NT_STATUS_FILE_IS_A_DIRECTORY;
8763                 }
8764                 create_options &= ~FILE_NON_DIRECTORY_FILE;
8765                 create_options |= FILE_DIRECTORY_FILE;
8766         }
8767
8768         DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
8769                 smb_fname_str_dbg(smb_fname),
8770                 (unsigned int)wire_open_mode,
8771                 (unsigned int)unixmode ));
8772
8773         status = SMB_VFS_CREATE_FILE(
8774                 conn,                                   /* conn */
8775                 req,                                    /* req */
8776                 0,                                      /* root_dir_fid */
8777                 smb_fname,                              /* fname */
8778                 access_mask,                            /* access_mask */
8779                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
8780                     FILE_SHARE_DELETE),
8781                 create_disp,                            /* create_disposition*/
8782                 create_options,                         /* create_options */
8783                 attributes,                             /* file_attributes */
8784                 oplock_request,                         /* oplock_request */
8785                 NULL,                                   /* lease */
8786                 0,                                      /* allocation_size */
8787                 0,                                      /* private_flags */
8788                 NULL,                                   /* sd */
8789                 NULL,                                   /* ea_list */
8790                 &fsp,                                   /* result */
8791                 &info,                                  /* pinfo */
8792                 posx,                                   /* in_context_blobs */
8793                 NULL);                                  /* out_context_blobs */
8794
8795         TALLOC_FREE(posx);
8796
8797         if (!NT_STATUS_IS_OK(status)) {
8798                 return status;
8799         }
8800
8801         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
8802                 extended_oplock_granted = True;
8803         }
8804
8805         if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
8806                 extended_oplock_granted = True;
8807         }
8808
8809         info_level_return = SVAL(pdata,16);
8810  
8811         /* Allocate the correct return size. */
8812
8813         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
8814                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
8815         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
8816                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
8817         } else {
8818                 *pdata_return_size = 12;
8819         }
8820
8821         /* Realloc the data size */
8822         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
8823         if (*ppdata == NULL) {
8824                 close_file(req, fsp, ERROR_CLOSE);
8825                 *pdata_return_size = 0;
8826                 return NT_STATUS_NO_MEMORY;
8827         }
8828         pdata = *ppdata;
8829
8830         if (extended_oplock_granted) {
8831                 if (flags & REQUEST_BATCH_OPLOCK) {
8832                         SSVAL(pdata,0, BATCH_OPLOCK_RETURN);
8833                 } else {
8834                         SSVAL(pdata,0, EXCLUSIVE_OPLOCK_RETURN);
8835                 }
8836         } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
8837                 SSVAL(pdata,0, LEVEL_II_OPLOCK_RETURN);
8838         } else {
8839                 SSVAL(pdata,0,NO_OPLOCK_RETURN);
8840         }
8841
8842         SSVAL(pdata,2,fsp->fnum);
8843         SIVAL(pdata,4,info); /* Was file created etc. */
8844
8845         switch (info_level_return) {
8846                 case SMB_QUERY_FILE_UNIX_BASIC:
8847                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
8848                         SSVAL(pdata,10,0); /* padding. */
8849                         store_file_unix_basic(conn, pdata + 12, fsp,
8850                                               &smb_fname->st);
8851                         break;
8852                 case SMB_QUERY_FILE_UNIX_INFO2:
8853                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
8854                         SSVAL(pdata,10,0); /* padding. */
8855                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
8856                                                     &smb_fname->st);
8857                         break;
8858                 default:
8859                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
8860                         SSVAL(pdata,10,0); /* padding. */
8861                         break;
8862         }
8863         return NT_STATUS_OK;
8864 }
8865
8866 /****************************************************************************
8867  Delete a file with POSIX semantics.
8868 ****************************************************************************/
8869
8870 static NTSTATUS smb_posix_unlink(connection_struct *conn,
8871                                  struct smb_request *req,
8872                                 const char *pdata,
8873                                 int total_data,
8874                                 struct smb_filename *smb_fname)
8875 {
8876         NTSTATUS status = NT_STATUS_OK;
8877         files_struct *fsp = NULL;
8878         uint16_t flags = 0;
8879         char del = 1;
8880         int info = 0;
8881         int create_options = 0;
8882         struct share_mode_lock *lck = NULL;
8883         bool other_nonposix_opens;
8884         struct smb2_create_blobs *posx = NULL;
8885
8886         if (total_data < 2) {
8887                 return NT_STATUS_INVALID_PARAMETER;
8888         }
8889
8890         flags = SVAL(pdata,0);
8891
8892         if (!VALID_STAT(smb_fname->st)) {
8893                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
8894         }
8895
8896         if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
8897                         !VALID_STAT_OF_DIR(smb_fname->st)) {
8898                 return NT_STATUS_NOT_A_DIRECTORY;
8899         }
8900
8901         DEBUG(10,("smb_posix_unlink: %s %s\n",
8902                 (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
8903                 smb_fname_str_dbg(smb_fname)));
8904
8905         if (VALID_STAT_OF_DIR(smb_fname->st)) {
8906                 create_options |= FILE_DIRECTORY_FILE;
8907         }
8908
8909         status = make_smb2_posix_create_ctx(talloc_tos(), &posx, 0777);
8910         if (!NT_STATUS_IS_OK(status)) {
8911                 DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
8912                             nt_errstr(status));
8913                 return status;
8914         }
8915
8916         status = SMB_VFS_CREATE_FILE(
8917                 conn,                                   /* conn */
8918                 req,                                    /* req */
8919                 0,                                      /* root_dir_fid */
8920                 smb_fname,                              /* fname */
8921                 DELETE_ACCESS,                          /* access_mask */
8922                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
8923                     FILE_SHARE_DELETE),
8924                 FILE_OPEN,                              /* create_disposition*/
8925                 create_options,                         /* create_options */
8926                 0,                                      /* file_attributes */
8927                 0,                                      /* oplock_request */
8928                 NULL,                                   /* lease */
8929                 0,                                      /* allocation_size */
8930                 0,                                      /* private_flags */
8931                 NULL,                                   /* sd */
8932                 NULL,                                   /* ea_list */
8933                 &fsp,                                   /* result */
8934                 &info,                                  /* pinfo */
8935                 posx,                                   /* in_context_blobs */
8936                 NULL);                                  /* out_context_blobs */
8937
8938         TALLOC_FREE(posx);
8939
8940         if (!NT_STATUS_IS_OK(status)) {
8941                 return status;
8942         }
8943
8944         /*
8945          * Don't lie to client. If we can't really delete due to
8946          * non-POSIX opens return SHARING_VIOLATION.
8947          */
8948
8949         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
8950         if (lck == NULL) {
8951                 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
8952                           "lock for file %s\n", fsp_str_dbg(fsp)));
8953                 close_file(req, fsp, NORMAL_CLOSE);
8954                 return NT_STATUS_INVALID_PARAMETER;
8955         }
8956
8957         other_nonposix_opens = has_other_nonposix_opens(lck, fsp);
8958         if (other_nonposix_opens) {
8959                 /* Fail with sharing violation. */
8960                 TALLOC_FREE(lck);
8961                 close_file(req, fsp, NORMAL_CLOSE);
8962                 return NT_STATUS_SHARING_VIOLATION;
8963         }
8964
8965         /*
8966          * Set the delete on close.
8967          */
8968         status = smb_set_file_disposition_info(conn,
8969                                                 &del,
8970                                                 1,
8971                                                 fsp,
8972                                                 smb_fname);
8973
8974         TALLOC_FREE(lck);
8975
8976         if (!NT_STATUS_IS_OK(status)) {
8977                 close_file(req, fsp, NORMAL_CLOSE);
8978                 return status;
8979         }
8980         return close_file(req, fsp, NORMAL_CLOSE);
8981 }
8982
8983 NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
8984                                 struct smb_request *req,
8985                                 TALLOC_CTX *mem_ctx,
8986                                 uint16_t info_level,
8987                                 files_struct *fsp,
8988                                 struct smb_filename *smb_fname,
8989                                 char **ppdata, int total_data,
8990                                 int *ret_data_size)
8991 {
8992         char *pdata = *ppdata;
8993         NTSTATUS status = NT_STATUS_OK;
8994         int data_return_size = 0;
8995
8996         *ret_data_size = 0;
8997
8998         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
8999                 return NT_STATUS_INVALID_LEVEL;
9000         }
9001
9002         if (!CAN_WRITE(conn)) {
9003                 /* Allow POSIX opens. The open path will deny
9004                  * any non-readonly opens. */
9005                 if (info_level != SMB_POSIX_PATH_OPEN) {
9006                         return NT_STATUS_DOS(ERRSRV, ERRaccess);
9007                 }
9008         }
9009
9010         DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "
9011                  "totdata=%d\n", smb_fname_str_dbg(smb_fname),
9012                  fsp_fnum_dbg(fsp),
9013                  info_level, total_data));
9014
9015         switch (info_level) {
9016
9017                 case SMB_INFO_STANDARD:
9018                 {
9019                         status = smb_set_info_standard(conn,
9020                                         pdata,
9021                                         total_data,
9022                                         fsp,
9023                                         smb_fname);
9024                         break;
9025                 }
9026
9027                 case SMB_INFO_SET_EA:
9028                 {
9029                         status = smb_info_set_ea(conn,
9030                                                 pdata,
9031                                                 total_data,
9032                                                 fsp,
9033                                                 smb_fname);
9034                         break;
9035                 }
9036
9037                 case SMB_SET_FILE_BASIC_INFO:
9038                 case SMB_FILE_BASIC_INFORMATION:
9039                 {
9040                         status = smb_set_file_basic_info(conn,
9041                                                         pdata,
9042                                                         total_data,
9043                                                         fsp,
9044                                                         smb_fname);
9045                         break;
9046                 }
9047
9048                 case SMB_FILE_ALLOCATION_INFORMATION:
9049                 case SMB_SET_FILE_ALLOCATION_INFO:
9050                 {
9051                         status = smb_set_file_allocation_info(conn, req,
9052                                                                 pdata,
9053                                                                 total_data,
9054                                                                 fsp,
9055                                                                 smb_fname);
9056                         break;
9057                 }
9058
9059                 case SMB_FILE_END_OF_FILE_INFORMATION:
9060                 case SMB_SET_FILE_END_OF_FILE_INFO:
9061                 {
9062                         /*
9063                          * XP/Win7 both fail after the createfile with
9064                          * SMB_SET_FILE_END_OF_FILE_INFO but not
9065                          * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
9066                          * The level is known here, so pass it down
9067                          * appropriately.
9068                          */
9069                         bool should_fail =
9070                             (info_level == SMB_SET_FILE_END_OF_FILE_INFO);
9071
9072                         status = smb_set_file_end_of_file_info(conn, req,
9073                                                                 pdata,
9074                                                                 total_data,
9075                                                                 fsp,
9076                                                                 smb_fname,
9077                                                                 should_fail);
9078                         break;
9079                 }
9080
9081                 case SMB_FILE_DISPOSITION_INFORMATION:
9082                 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
9083                 {
9084 #if 0
9085                         /* JRA - We used to just ignore this on a path ? 
9086                          * Shouldn't this be invalid level on a pathname
9087                          * based call ?
9088                          */
9089                         if (tran_call != TRANSACT2_SETFILEINFO) {
9090                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
9091                         }
9092 #endif
9093                         status = smb_set_file_disposition_info(conn,
9094                                                 pdata,
9095                                                 total_data,
9096                                                 fsp,
9097                                                 smb_fname);
9098                         break;
9099                 }
9100
9101                 case SMB_FILE_POSITION_INFORMATION:
9102                 {
9103                         status = smb_file_position_information(conn,
9104                                                 pdata,
9105                                                 total_data,
9106                                                 fsp);
9107                         break;
9108                 }
9109
9110                 case SMB_FILE_FULL_EA_INFORMATION:
9111                 {
9112                         status = smb_set_file_full_ea_info(conn,
9113                                                 pdata,
9114                                                 total_data,
9115                                                 fsp);
9116                         break;
9117                 }
9118
9119                 /* From tridge Samba4 : 
9120                  * MODE_INFORMATION in setfileinfo (I have no
9121                  * idea what "mode information" on a file is - it takes a value of 0,
9122                  * 2, 4 or 6. What could it be?).
9123                  */
9124
9125                 case SMB_FILE_MODE_INFORMATION:
9126                 {
9127                         status = smb_file_mode_information(conn,
9128                                                 pdata,
9129                                                 total_data);
9130                         break;
9131                 }
9132
9133                 /* [MS-SMB2] 3.3.5.21.1 states we MUST fail with STATUS_NOT_SUPPORTED. */
9134                 case SMB_FILE_VALID_DATA_LENGTH_INFORMATION:
9135                 case SMB_FILE_SHORT_NAME_INFORMATION:
9136                         return NT_STATUS_NOT_SUPPORTED;
9137
9138                 /*
9139                  * CIFS UNIX extensions.
9140                  */
9141
9142                 case SMB_SET_FILE_UNIX_BASIC:
9143                 {
9144                         status = smb_set_file_unix_basic(conn, req,
9145                                                         pdata,
9146                                                         total_data,
9147                                                         fsp,
9148                                                         smb_fname);
9149                         break;
9150                 }
9151
9152                 case SMB_SET_FILE_UNIX_INFO2:
9153                 {
9154                         status = smb_set_file_unix_info2(conn, req,
9155                                                         pdata,
9156                                                         total_data,
9157                                                         fsp,
9158                                                         smb_fname);
9159                         break;
9160                 }
9161
9162                 case SMB_SET_FILE_UNIX_LINK:
9163                 {
9164                         if (fsp) {
9165                                 /* We must have a pathname for this. */
9166                                 return NT_STATUS_INVALID_LEVEL;
9167                         }
9168                         status = smb_set_file_unix_link(conn, req, pdata,
9169                                                         total_data, smb_fname);
9170                         break;
9171                 }
9172
9173                 case SMB_SET_FILE_UNIX_HLINK:
9174                 {
9175                         if (fsp) {
9176                                 /* We must have a pathname for this. */
9177                                 return NT_STATUS_INVALID_LEVEL;
9178                         }
9179                         status = smb_set_file_unix_hlink(conn, req,
9180                                                          pdata, total_data,
9181                                                          smb_fname);
9182                         break;
9183                 }
9184
9185                 case SMB_FILE_RENAME_INFORMATION:
9186                 {
9187                         status = smb_file_rename_information(conn, req,
9188                                                              pdata, total_data,
9189                                                              fsp, smb_fname);
9190                         break;
9191                 }
9192
9193                 case SMB2_FILE_RENAME_INFORMATION_INTERNAL:
9194                 {
9195                         /* SMB2 rename information. */
9196                         status = smb2_file_rename_information(conn, req,
9197                                                              pdata, total_data,
9198                                                              fsp, smb_fname);
9199                         break;
9200                 }
9201
9202                 case SMB_FILE_LINK_INFORMATION:
9203                 {
9204                         status = smb_file_link_information(conn, req,
9205                                                         pdata, total_data,
9206                                                         fsp, smb_fname);
9207                         break;
9208                 }
9209
9210 #if defined(HAVE_POSIX_ACLS)
9211                 case SMB_SET_POSIX_ACL:
9212                 {
9213                         status = smb_set_posix_acl(conn,
9214                                                 req,
9215                                                 pdata,
9216                                                 total_data,
9217                                                 fsp,
9218                                                 smb_fname);
9219                         break;
9220                 }
9221 #endif
9222
9223                 case SMB_SET_POSIX_LOCK:
9224                 {
9225                         if (!fsp) {
9226                                 return NT_STATUS_INVALID_LEVEL;
9227                         }
9228                         status = smb_set_posix_lock(conn, req,
9229                                                     pdata, total_data, fsp);
9230                         break;
9231                 }
9232
9233                 case SMB_POSIX_PATH_OPEN:
9234                 {
9235                         if (fsp) {
9236                                 /* We must have a pathname for this. */
9237                                 return NT_STATUS_INVALID_LEVEL;
9238                         }
9239
9240                         status = smb_posix_open(conn, req,
9241                                                 ppdata,
9242                                                 total_data,
9243                                                 smb_fname,
9244                                                 &data_return_size);
9245                         break;
9246                 }
9247
9248                 case SMB_POSIX_PATH_UNLINK:
9249                 {
9250                         if (fsp) {
9251                                 /* We must have a pathname for this. */
9252                                 return NT_STATUS_INVALID_LEVEL;
9253                         }
9254
9255                         status = smb_posix_unlink(conn, req,
9256                                                 pdata,
9257                                                 total_data,
9258                                                 smb_fname);
9259                         break;
9260                 }
9261
9262                 default:
9263                         return NT_STATUS_INVALID_LEVEL;
9264         }
9265
9266         if (!NT_STATUS_IS_OK(status)) {
9267                 return status;
9268         }
9269
9270         *ret_data_size = data_return_size;
9271         return NT_STATUS_OK;
9272 }
9273
9274 /****************************************************************************
9275  Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
9276 ****************************************************************************/
9277
9278 static void call_trans2setfilepathinfo(connection_struct *conn,
9279                                        struct smb_request *req,
9280                                        unsigned int tran_call,
9281                                        char **pparams, int total_params,
9282                                        char **ppdata, int total_data,
9283                                        unsigned int max_data_bytes)
9284 {
9285         char *params = *pparams;
9286         char *pdata = *ppdata;
9287         uint16_t info_level;
9288         struct smb_filename *smb_fname = NULL;
9289         files_struct *fsp = NULL;
9290         NTSTATUS status = NT_STATUS_OK;
9291         int data_return_size = 0;
9292
9293         if (!params) {
9294                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9295                 return;
9296         }
9297
9298         if (tran_call == TRANSACT2_SETFILEINFO) {
9299                 if (total_params < 4) {
9300                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9301                         return;
9302                 }
9303
9304                 fsp = file_fsp(req, SVAL(params,0));
9305                 /* Basic check for non-null fsp. */
9306                 if (!check_fsp_open(conn, req, fsp)) {
9307                         return;
9308                 }
9309                 info_level = SVAL(params,2);
9310
9311                 smb_fname = cp_smb_filename(talloc_tos(), fsp->fsp_name);
9312                 if (smb_fname == NULL) {
9313                         reply_nterror(req, NT_STATUS_NO_MEMORY);
9314                         return;
9315                 }
9316
9317                 if(fsp->fh->fd == -1) {
9318                         /*
9319                          * This is actually a SETFILEINFO on a directory
9320                          * handle (returned from an NT SMB). NT5.0 seems
9321                          * to do this call. JRA.
9322                          */
9323                         if (INFO_LEVEL_IS_UNIX(info_level)) {
9324                                 /* Always do lstat for UNIX calls. */
9325                                 if (SMB_VFS_LSTAT(conn, smb_fname)) {
9326                                         DEBUG(3,("call_trans2setfilepathinfo: "
9327                                                  "SMB_VFS_LSTAT of %s failed "
9328                                                  "(%s)\n",
9329                                                  smb_fname_str_dbg(smb_fname),
9330                                                  strerror(errno)));
9331                                         reply_nterror(req, map_nt_error_from_unix(errno));
9332                                         return;
9333                                 }
9334                         } else {
9335                                 if (SMB_VFS_STAT(conn, smb_fname) != 0) {
9336                                         DEBUG(3,("call_trans2setfilepathinfo: "
9337                                                  "fileinfo of %s failed (%s)\n",
9338                                                  smb_fname_str_dbg(smb_fname),
9339                                                  strerror(errno)));
9340                                         reply_nterror(req, map_nt_error_from_unix(errno));
9341                                         return;
9342                                 }
9343                         }
9344                 } else if (fsp->print_file) {
9345                         /*
9346                          * Doing a DELETE_ON_CLOSE should cancel a print job.
9347                          */
9348                         if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
9349                                 fsp->fh->private_options |= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE;
9350
9351                                 DEBUG(3,("call_trans2setfilepathinfo: "
9352                                          "Cancelling print job (%s)\n",
9353                                          fsp_str_dbg(fsp)));
9354
9355                                 SSVAL(params,0,0);
9356                                 send_trans2_replies(conn, req, NT_STATUS_OK, params, 2,
9357                                                     *ppdata, 0,
9358                                                     max_data_bytes);
9359                                 return;
9360                         } else {
9361                                 reply_nterror(req,
9362                                         NT_STATUS_OBJECT_PATH_NOT_FOUND);
9363                                 return;
9364                         }
9365                 } else {
9366                         /*
9367                          * Original code - this is an open file.
9368                          */
9369                         if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
9370                                 DEBUG(3,("call_trans2setfilepathinfo: fstat "
9371                                          "of %s failed (%s)\n", fsp_fnum_dbg(fsp),
9372                                          strerror(errno)));
9373                                 reply_nterror(req, map_nt_error_from_unix(errno));
9374                                 return;
9375                         }
9376                 }
9377         } else {
9378                 char *fname = NULL;
9379                 uint32_t ucf_flags = ucf_flags_from_smb_request(req);
9380
9381                 /* set path info */
9382                 if (total_params < 7) {
9383                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9384                         return;
9385                 }
9386
9387                 info_level = SVAL(params,0);
9388                 if (req->posix_pathnames) {
9389                         srvstr_get_path_posix(req,
9390                                 params,
9391                                 req->flags2,
9392                                 &fname,
9393                                 &params[6],
9394                                 total_params - 6,
9395                                 STR_TERMINATE,
9396                                 &status);
9397                 } else {
9398                         srvstr_get_path(req,
9399                                 params,
9400                                 req->flags2,
9401                                 &fname,
9402                                 &params[6],
9403                                 total_params - 6,
9404                                 STR_TERMINATE,
9405                                 &status);
9406                 }
9407                 if (!NT_STATUS_IS_OK(status)) {
9408                         reply_nterror(req, status);
9409                         return;
9410                 }
9411
9412                 if (info_level == SMB_SET_FILE_UNIX_BASIC ||
9413                                 info_level == SMB_SET_FILE_UNIX_INFO2 ||
9414                                 info_level == SMB_FILE_RENAME_INFORMATION ||
9415                                 info_level == SMB_POSIX_PATH_OPEN ||
9416                                 info_level == SMB_POSIX_PATH_UNLINK) {
9417                         ucf_flags |= UCF_UNIX_NAME_LOOKUP;
9418                 }
9419
9420                 status = filename_convert(req, conn,
9421                                          fname,
9422                                          ucf_flags,
9423                                          0,
9424                                          NULL,
9425                                          &smb_fname);
9426                 if (!NT_STATUS_IS_OK(status)) {
9427                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
9428                                 reply_botherror(req,
9429                                                 NT_STATUS_PATH_NOT_COVERED,
9430                                                 ERRSRV, ERRbadpath);
9431                                 return;
9432                         }
9433                         reply_nterror(req, status);
9434                         return;
9435                 }
9436
9437                 if (INFO_LEVEL_IS_UNIX(info_level)) {
9438                         /*
9439                          * For CIFS UNIX extensions the target name may not exist.
9440                          */
9441
9442                         /* Always do lstat for UNIX calls. */
9443                         SMB_VFS_LSTAT(conn, smb_fname);
9444
9445                 } else if (!VALID_STAT(smb_fname->st) &&
9446                            SMB_VFS_STAT(conn, smb_fname)) {
9447                         DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
9448                                  "%s failed (%s)\n",
9449                                  smb_fname_str_dbg(smb_fname),
9450                                  strerror(errno)));
9451                         reply_nterror(req, map_nt_error_from_unix(errno));
9452                         return;
9453                 }
9454         }
9455
9456         DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
9457                  "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
9458                  fsp_fnum_dbg(fsp),
9459                  info_level,total_data));
9460
9461         /* Realloc the parameter size */
9462         *pparams = (char *)SMB_REALLOC(*pparams,2);
9463         if (*pparams == NULL) {
9464                 reply_nterror(req, NT_STATUS_NO_MEMORY);
9465                 return;
9466         }
9467         params = *pparams;
9468
9469         SSVAL(params,0,0);
9470
9471         status = smbd_do_setfilepathinfo(conn, req, req,
9472                                          info_level,
9473                                          fsp,
9474                                          smb_fname,
9475                                          ppdata, total_data,
9476                                          &data_return_size);
9477         if (!NT_STATUS_IS_OK(status)) {
9478                 if (open_was_deferred(req->xconn, req->mid)) {
9479                         /* We have re-scheduled this call. */
9480                         return;
9481                 }
9482                 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
9483                         bool ok = defer_smb1_sharing_violation(req);
9484                         if (ok) {
9485                                 return;
9486                         }
9487                 }
9488                 if (NT_STATUS_EQUAL(status, NT_STATUS_EVENT_PENDING)) {
9489                         /* We have re-scheduled this call. */
9490                         return;
9491                 }
9492                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
9493                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
9494                                         ERRSRV, ERRbadpath);
9495                         return;
9496                 }
9497                 if (info_level == SMB_POSIX_PATH_OPEN) {
9498                         reply_openerror(req, status);
9499                         return;
9500                 }
9501
9502                 /*
9503                  * Invalid EA name needs to return 2 param bytes,
9504                  * not a zero-length error packet.
9505                  */
9506                 if (NT_STATUS_EQUAL(status, STATUS_INVALID_EA_NAME)) {
9507                         send_trans2_replies(conn, req, status, params, 2, NULL, 0,
9508                                         max_data_bytes);
9509                 } else {
9510                         reply_nterror(req, status);
9511                 }
9512                 return;
9513         }
9514
9515         send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, data_return_size,
9516                             max_data_bytes);
9517
9518         return;
9519 }
9520
9521 /****************************************************************************
9522  Reply to a TRANS2_MKDIR (make directory with extended attributes).
9523 ****************************************************************************/
9524
9525 static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
9526                              char **pparams, int total_params,
9527                              char **ppdata, int total_data,
9528                              unsigned int max_data_bytes)
9529 {
9530         struct smb_filename *smb_dname = NULL;
9531         char *params = *pparams;
9532         char *pdata = *ppdata;
9533         char *directory = NULL;
9534         NTSTATUS status = NT_STATUS_OK;
9535         struct ea_list *ea_list = NULL;
9536         uint32_t ucf_flags = ucf_flags_from_smb_request(req);
9537         TALLOC_CTX *ctx = talloc_tos();
9538
9539         if (!CAN_WRITE(conn)) {
9540                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9541                 return;
9542         }
9543
9544         if (total_params < 5) {
9545                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9546                 return;
9547         }
9548
9549         if (req->posix_pathnames) {
9550                 srvstr_get_path_posix(ctx,
9551                         params,
9552                         req->flags2,
9553                         &directory,
9554                         &params[4],
9555                         total_params - 4,
9556                         STR_TERMINATE,
9557                         &status);
9558         } else {
9559                 srvstr_get_path(ctx,
9560                         params,
9561                         req->flags2,
9562                         &directory,
9563                         &params[4],
9564                         total_params - 4,
9565                         STR_TERMINATE,
9566                         &status);
9567         }
9568         if (!NT_STATUS_IS_OK(status)) {
9569                 reply_nterror(req, status);
9570                 return;
9571         }
9572
9573         DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
9574
9575         status = filename_convert(ctx,
9576                                 conn,
9577                                 directory,
9578                                 ucf_flags,
9579                                 0,
9580                                 NULL,
9581                                 &smb_dname);
9582
9583         if (!NT_STATUS_IS_OK(status)) {
9584                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
9585                         reply_botherror(req,
9586                                 NT_STATUS_PATH_NOT_COVERED,
9587                                 ERRSRV, ERRbadpath);
9588                         return;
9589                 }
9590                 reply_nterror(req, status);
9591                 return;
9592         }
9593
9594         /*
9595          * OS/2 workplace shell seems to send SET_EA requests of "null"
9596          * length (4 bytes containing IVAL 4).
9597          * They seem to have no effect. Bug #3212. JRA.
9598          */
9599
9600         if (total_data && (total_data != 4)) {
9601                 /* Any data in this call is an EA list. */
9602                 if (total_data < 10) {
9603                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9604                         goto out;
9605                 }
9606
9607                 if (IVAL(pdata,0) > total_data) {
9608                         DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
9609                                 IVAL(pdata,0), (unsigned int)total_data));
9610                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9611                         goto out;
9612                 }
9613
9614                 ea_list = read_ea_list(talloc_tos(), pdata + 4,
9615                                        total_data - 4);
9616                 if (!ea_list) {
9617                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9618                         goto out;
9619                 }
9620
9621                 if (!lp_ea_support(SNUM(conn))) {
9622                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
9623                         goto out;
9624                 }
9625         }
9626         /* If total_data == 4 Windows doesn't care what values
9627          * are placed in that field, it just ignores them.
9628          * The System i QNTC IBM SMB client puts bad values here,
9629          * so ignore them. */
9630
9631         status = create_directory(conn, req, smb_dname);
9632
9633         if (!NT_STATUS_IS_OK(status)) {
9634                 reply_nterror(req, status);
9635                 goto out;
9636         }
9637
9638         /* Try and set any given EA. */
9639         if (ea_list) {
9640                 status = set_ea(conn, NULL, smb_dname, ea_list);
9641                 if (!NT_STATUS_IS_OK(status)) {
9642                         reply_nterror(req, status);
9643                         goto out;
9644                 }
9645         }
9646
9647         /* Realloc the parameter and data sizes */
9648         *pparams = (char *)SMB_REALLOC(*pparams,2);
9649         if(*pparams == NULL) {
9650                 reply_nterror(req, NT_STATUS_NO_MEMORY);
9651                 goto out;
9652         }
9653         params = *pparams;
9654
9655         SSVAL(params,0,0);
9656
9657         send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, 0, max_data_bytes);
9658
9659  out:
9660         TALLOC_FREE(smb_dname);
9661         return;
9662 }
9663
9664 /****************************************************************************
9665  Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
9666  We don't actually do this - we just send a null response.
9667 ****************************************************************************/
9668
9669 static void call_trans2findnotifyfirst(connection_struct *conn,
9670                                        struct smb_request *req,
9671                                        char **pparams, int total_params,
9672                                        char **ppdata, int total_data,
9673                                        unsigned int max_data_bytes)
9674 {
9675         char *params = *pparams;
9676         uint16_t info_level;
9677
9678         if (total_params < 6) {
9679                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9680                 return;
9681         }
9682
9683         info_level = SVAL(params,4);
9684         DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
9685
9686         switch (info_level) {
9687                 case 1:
9688                 case 2:
9689                         break;
9690                 default:
9691                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
9692                         return;
9693         }
9694
9695         /* Realloc the parameter and data sizes */
9696         *pparams = (char *)SMB_REALLOC(*pparams,6);
9697         if (*pparams == NULL) {
9698                 reply_nterror(req, NT_STATUS_NO_MEMORY);
9699                 return;
9700         }
9701         params = *pparams;
9702
9703         SSVAL(params,0,fnf_handle);
9704         SSVAL(params,2,0); /* No changes */
9705         SSVAL(params,4,0); /* No EA errors */
9706
9707         fnf_handle++;
9708
9709         if(fnf_handle == 0)
9710                 fnf_handle = 257;
9711
9712         send_trans2_replies(conn, req, NT_STATUS_OK, params, 6, *ppdata, 0, max_data_bytes);
9713
9714         return;
9715 }
9716
9717 /****************************************************************************
9718  Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for 
9719  changes). Currently this does nothing.
9720 ****************************************************************************/
9721
9722 static void call_trans2findnotifynext(connection_struct *conn,
9723                                       struct smb_request *req,
9724                                       char **pparams, int total_params,
9725                                       char **ppdata, int total_data,
9726                                       unsigned int max_data_bytes)
9727 {
9728         char *params = *pparams;
9729
9730         DEBUG(3,("call_trans2findnotifynext\n"));
9731
9732         /* Realloc the parameter and data sizes */
9733         *pparams = (char *)SMB_REALLOC(*pparams,4);
9734         if (*pparams == NULL) {
9735                 reply_nterror(req, NT_STATUS_NO_MEMORY);
9736                 return;
9737         }
9738         params = *pparams;
9739
9740         SSVAL(params,0,0); /* No changes */
9741         SSVAL(params,2,0); /* No EA errors */
9742
9743         send_trans2_replies(conn, req, NT_STATUS_OK, params, 4, *ppdata, 0, max_data_bytes);
9744
9745         return;
9746 }
9747
9748 /****************************************************************************
9749  Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
9750 ****************************************************************************/
9751
9752 static void call_trans2getdfsreferral(connection_struct *conn,
9753                                       struct smb_request *req,
9754                                       char **pparams, int total_params,
9755                                       char **ppdata, int total_data,
9756                                       unsigned int max_data_bytes)
9757 {
9758         char *params = *pparams;
9759         char *pathname = NULL;
9760         int reply_size = 0;
9761         int max_referral_level;
9762         NTSTATUS status = NT_STATUS_OK;
9763         TALLOC_CTX *ctx = talloc_tos();
9764
9765         DEBUG(10,("call_trans2getdfsreferral\n"));
9766
9767         if (total_params < 3) {
9768                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9769                 return;
9770         }
9771
9772         max_referral_level = SVAL(params,0);
9773
9774         if(!lp_host_msdfs()) {
9775                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
9776                 return;
9777         }
9778
9779         srvstr_pull_talloc(ctx, params, req->flags2, &pathname, &params[2],
9780                     total_params - 2, STR_TERMINATE);
9781         if (!pathname) {
9782                 reply_nterror(req, NT_STATUS_NOT_FOUND);
9783                 return;
9784         }
9785         if((reply_size = setup_dfs_referral(conn, pathname, max_referral_level,
9786                                             ppdata,&status)) < 0) {
9787                 reply_nterror(req, status);
9788                 return;
9789         }
9790
9791         SSVAL((discard_const_p(uint8_t, req->inbuf)), smb_flg2,
9792               SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
9793         send_trans2_replies(conn, req, NT_STATUS_OK, 0,0,*ppdata,reply_size, max_data_bytes);
9794
9795         return;
9796 }
9797
9798 #define LMCAT_SPL       0x53
9799 #define LMFUNC_GETJOBID 0x60
9800
9801 /****************************************************************************
9802  Reply to a TRANS2_IOCTL - used for OS/2 printing.
9803 ****************************************************************************/
9804
9805 static void call_trans2ioctl(connection_struct *conn,
9806                              struct smb_request *req,
9807                              char **pparams, int total_params,
9808                              char **ppdata, int total_data,
9809                              unsigned int max_data_bytes)
9810 {
9811         const struct loadparm_substitution *lp_sub =
9812                 loadparm_s3_global_substitution();
9813         char *pdata = *ppdata;
9814         files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0));
9815         NTSTATUS status;
9816         size_t len = 0;
9817
9818         /* check for an invalid fid before proceeding */
9819
9820         if (!fsp) {
9821                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
9822                 return;
9823         }
9824
9825         if ((SVAL(req->vwv+16, 0) == LMCAT_SPL)
9826             && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
9827                 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
9828                 if (*ppdata == NULL) {
9829                         reply_nterror(req, NT_STATUS_NO_MEMORY);
9830                         return;
9831                 }
9832                 pdata = *ppdata;
9833
9834                 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
9835                         CAN ACCEPT THIS IN UNICODE. JRA. */
9836
9837                 /* Job number */
9838                 SSVAL(pdata, 0, print_spool_rap_jobid(fsp->print_file));
9839
9840                 status = srvstr_push(pdata, req->flags2, pdata + 2,
9841                             lp_netbios_name(), 15,
9842                             STR_ASCII|STR_TERMINATE, &len); /* Our NetBIOS name */
9843                 if (!NT_STATUS_IS_OK(status)) {
9844                         reply_nterror(req, status);
9845                         return;
9846                 }
9847                 status = srvstr_push(pdata, req->flags2, pdata+18,
9848                             lp_servicename(talloc_tos(), lp_sub, SNUM(conn)), 13,
9849                             STR_ASCII|STR_TERMINATE, &len); /* Service name */
9850                 if (!NT_STATUS_IS_OK(status)) {
9851                         reply_nterror(req, status);
9852                         return;
9853                 }
9854                 send_trans2_replies(conn, req, NT_STATUS_OK, *pparams, 0, *ppdata, 32,
9855                                     max_data_bytes);
9856                 return;
9857         }
9858
9859         DEBUG(2,("Unknown TRANS2_IOCTL\n"));
9860         reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
9861 }
9862
9863 /****************************************************************************
9864  Reply to a SMBfindclose (stop trans2 directory search).
9865 ****************************************************************************/
9866
9867 void reply_findclose(struct smb_request *req)
9868 {
9869         int dptr_num;
9870         struct smbd_server_connection *sconn = req->sconn;
9871         files_struct *fsp = NULL;
9872
9873         START_PROFILE(SMBfindclose);
9874
9875         if (req->wct < 1) {
9876                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9877                 END_PROFILE(SMBfindclose);
9878                 return;
9879         }
9880
9881         dptr_num = SVALS(req->vwv+0, 0);
9882
9883         DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
9884
9885         /*
9886          * OS/2 seems to use -1 to indicate "close all directories"
9887          * This has to mean on this specific connection struct.
9888          */
9889         if (dptr_num == -1) {
9890                 dptr_closecnum(req->conn);
9891         } else {
9892                 fsp = dptr_fetch_lanman2_fsp(sconn, dptr_num);
9893                 dptr_num = -1;
9894                 if (fsp != NULL) {
9895                         close_file(NULL, fsp, NORMAL_CLOSE);
9896                         fsp = NULL;
9897                 }
9898         }
9899
9900         reply_outbuf(req, 0, 0);
9901
9902         DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
9903
9904         END_PROFILE(SMBfindclose);
9905         return;
9906 }
9907
9908 /****************************************************************************
9909  Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
9910 ****************************************************************************/
9911
9912 void reply_findnclose(struct smb_request *req)
9913 {
9914         int dptr_num;
9915
9916         START_PROFILE(SMBfindnclose);
9917
9918         if (req->wct < 1) {
9919                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9920                 END_PROFILE(SMBfindnclose);
9921                 return;
9922         }
9923
9924         dptr_num = SVAL(req->vwv+0, 0);
9925
9926         DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
9927
9928         /* We never give out valid handles for a 
9929            findnotifyfirst - so any dptr_num is ok here. 
9930            Just ignore it. */
9931
9932         reply_outbuf(req, 0, 0);
9933
9934         DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
9935
9936         END_PROFILE(SMBfindnclose);
9937         return;
9938 }
9939
9940 static void handle_trans2(connection_struct *conn, struct smb_request *req,
9941                           struct trans_state *state)
9942 {
9943         if (get_Protocol() >= PROTOCOL_NT1) {
9944                 req->flags2 |= 0x40; /* IS_LONG_NAME */
9945                 SSVAL((discard_const_p(uint8_t, req->inbuf)),smb_flg2,req->flags2);
9946         }
9947
9948         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
9949                 if (state->call != TRANSACT2_QFSINFO &&
9950                     state->call != TRANSACT2_SETFSINFO) {
9951                         DEBUG(0,("handle_trans2: encryption required "
9952                                 "with call 0x%x\n",
9953                                 (unsigned int)state->call));
9954                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9955                         return;
9956                 }
9957         }
9958
9959         SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
9960
9961         /* Now we must call the relevant TRANS2 function */
9962         switch(state->call)  {
9963         case TRANSACT2_OPEN:
9964         {
9965                 START_PROFILE(Trans2_open);
9966                 call_trans2open(conn, req,
9967                                 &state->param, state->total_param,
9968                                 &state->data, state->total_data,
9969                                 state->max_data_return);
9970                 END_PROFILE(Trans2_open);
9971                 break;
9972         }
9973
9974         case TRANSACT2_FINDFIRST:
9975         {
9976                 START_PROFILE(Trans2_findfirst);
9977                 call_trans2findfirst(conn, req,
9978                                      &state->param, state->total_param,
9979                                      &state->data, state->total_data,
9980                                      state->max_data_return);
9981                 END_PROFILE(Trans2_findfirst);
9982                 break;
9983         }
9984
9985         case TRANSACT2_FINDNEXT:
9986         {
9987                 START_PROFILE(Trans2_findnext);
9988                 call_trans2findnext(conn, req,
9989                                     &state->param, state->total_param,
9990                                     &state->data, state->total_data,
9991                                     state->max_data_return);
9992                 END_PROFILE(Trans2_findnext);
9993                 break;
9994         }
9995
9996         case TRANSACT2_QFSINFO:
9997         {
9998                 START_PROFILE(Trans2_qfsinfo);
9999                 call_trans2qfsinfo(conn, req,
10000                                    &state->param, state->total_param,
10001                                    &state->data, state->total_data,
10002                                    state->max_data_return);
10003                 END_PROFILE(Trans2_qfsinfo);
10004             break;
10005         }
10006
10007         case TRANSACT2_SETFSINFO:
10008         {
10009                 START_PROFILE(Trans2_setfsinfo);
10010                 call_trans2setfsinfo(conn, req,
10011                                      &state->param, state->total_param,
10012                                      &state->data, state->total_data,
10013                                      state->max_data_return);
10014                 END_PROFILE(Trans2_setfsinfo);
10015                 break;
10016         }
10017
10018         case TRANSACT2_QPATHINFO:
10019         case TRANSACT2_QFILEINFO:
10020         {
10021                 START_PROFILE(Trans2_qpathinfo);
10022                 call_trans2qfilepathinfo(conn, req, state->call,
10023                                          &state->param, state->total_param,
10024                                          &state->data, state->total_data,
10025                                          state->max_data_return);
10026                 END_PROFILE(Trans2_qpathinfo);
10027                 break;
10028         }
10029
10030         case TRANSACT2_SETPATHINFO:
10031         case TRANSACT2_SETFILEINFO:
10032         {
10033                 START_PROFILE(Trans2_setpathinfo);
10034                 call_trans2setfilepathinfo(conn, req, state->call,
10035                                            &state->param, state->total_param,
10036                                            &state->data, state->total_data,
10037                                            state->max_data_return);
10038                 END_PROFILE(Trans2_setpathinfo);
10039                 break;
10040         }
10041
10042         case TRANSACT2_FINDNOTIFYFIRST:
10043         {
10044                 START_PROFILE(Trans2_findnotifyfirst);
10045                 call_trans2findnotifyfirst(conn, req,
10046                                            &state->param, state->total_param,
10047                                            &state->data, state->total_data,
10048                                            state->max_data_return);
10049                 END_PROFILE(Trans2_findnotifyfirst);
10050                 break;
10051         }
10052
10053         case TRANSACT2_FINDNOTIFYNEXT:
10054         {
10055                 START_PROFILE(Trans2_findnotifynext);
10056                 call_trans2findnotifynext(conn, req,
10057                                           &state->param, state->total_param,
10058                                           &state->data, state->total_data,
10059                                           state->max_data_return);
10060                 END_PROFILE(Trans2_findnotifynext);
10061                 break;
10062         }
10063
10064         case TRANSACT2_MKDIR:
10065         {
10066                 START_PROFILE(Trans2_mkdir);
10067                 call_trans2mkdir(conn, req,
10068                                  &state->param, state->total_param,
10069                                  &state->data, state->total_data,
10070                                  state->max_data_return);
10071                 END_PROFILE(Trans2_mkdir);
10072                 break;
10073         }
10074
10075         case TRANSACT2_GET_DFS_REFERRAL:
10076         {
10077                 START_PROFILE(Trans2_get_dfs_referral);
10078                 call_trans2getdfsreferral(conn, req,
10079                                           &state->param, state->total_param,
10080                                           &state->data, state->total_data,
10081                                           state->max_data_return);
10082                 END_PROFILE(Trans2_get_dfs_referral);
10083                 break;
10084         }
10085
10086         case TRANSACT2_IOCTL:
10087         {
10088                 START_PROFILE(Trans2_ioctl);
10089                 call_trans2ioctl(conn, req,
10090                                  &state->param, state->total_param,
10091                                  &state->data, state->total_data,
10092                                  state->max_data_return);
10093                 END_PROFILE(Trans2_ioctl);
10094                 break;
10095         }
10096
10097         default:
10098                 /* Error in request */
10099                 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
10100                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
10101         }
10102 }
10103
10104 /****************************************************************************
10105  Reply to a SMBtrans2.
10106  ****************************************************************************/
10107
10108 void reply_trans2(struct smb_request *req)
10109 {
10110         connection_struct *conn = req->conn;
10111         unsigned int dsoff;
10112         unsigned int dscnt;
10113         unsigned int psoff;
10114         unsigned int pscnt;
10115         unsigned int tran_call;
10116         struct trans_state *state;
10117         NTSTATUS result;
10118
10119         START_PROFILE(SMBtrans2);
10120
10121         if (req->wct < 14) {
10122                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10123                 END_PROFILE(SMBtrans2);
10124                 return;
10125         }
10126
10127         dsoff = SVAL(req->vwv+12, 0);
10128         dscnt = SVAL(req->vwv+11, 0);
10129         psoff = SVAL(req->vwv+10, 0);
10130         pscnt = SVAL(req->vwv+9, 0);
10131         tran_call = SVAL(req->vwv+14, 0);
10132
10133         result = allow_new_trans(conn->pending_trans, req->mid);
10134         if (!NT_STATUS_IS_OK(result)) {
10135                 DEBUG(2, ("Got invalid trans2 request: %s\n",
10136                           nt_errstr(result)));
10137                 reply_nterror(req, result);
10138                 END_PROFILE(SMBtrans2);
10139                 return;
10140         }
10141
10142         if (IS_IPC(conn)) {
10143                 switch (tran_call) {
10144                 /* List the allowed trans2 calls on IPC$ */
10145                 case TRANSACT2_OPEN:
10146                 case TRANSACT2_GET_DFS_REFERRAL:
10147                 case TRANSACT2_QFILEINFO:
10148                 case TRANSACT2_QFSINFO:
10149                 case TRANSACT2_SETFSINFO:
10150                         break;
10151                 default:
10152                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
10153                         END_PROFILE(SMBtrans2);
10154                         return;
10155                 }
10156         }
10157
10158         if ((state = talloc(conn, struct trans_state)) == NULL) {
10159                 DEBUG(0, ("talloc failed\n"));
10160                 reply_nterror(req, NT_STATUS_NO_MEMORY);
10161                 END_PROFILE(SMBtrans2);
10162                 return;
10163         }
10164
10165         state->cmd = SMBtrans2;
10166
10167         state->mid = req->mid;
10168         state->vuid = req->vuid;
10169         state->setup_count = SVAL(req->vwv+13, 0);
10170         state->setup = NULL;
10171         state->total_param = SVAL(req->vwv+0, 0);
10172         state->param = NULL;
10173         state->total_data =  SVAL(req->vwv+1, 0);
10174         state->data = NULL;
10175         state->max_param_return = SVAL(req->vwv+2, 0);
10176         state->max_data_return  = SVAL(req->vwv+3, 0);
10177         state->max_setup_return = SVAL(req->vwv+4, 0);
10178         state->close_on_completion = BITSETW(req->vwv+5, 0);
10179         state->one_way = BITSETW(req->vwv+5, 1);
10180
10181         state->call = tran_call;
10182
10183         /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
10184            is so as a sanity check */
10185         if (state->setup_count != 1) {
10186                 /*
10187                  * Need to have rc=0 for ioctl to get job id for OS/2.
10188                  *  Network printing will fail if function is not successful.
10189                  *  Similar function in reply.c will be used if protocol
10190                  *  is LANMAN1.0 instead of LM1.2X002.
10191                  *  Until DosPrintSetJobInfo with PRJINFO3 is supported,
10192                  *  outbuf doesn't have to be set(only job id is used).
10193                  */
10194                 if ( (state->setup_count == 4)
10195                      && (tran_call == TRANSACT2_IOCTL)
10196                      && (SVAL(req->vwv+16, 0) == LMCAT_SPL)
10197                      && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
10198                         DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
10199                 } else {
10200                         DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
10201                         DEBUG(2,("Transaction is %d\n",tran_call));
10202                         TALLOC_FREE(state);
10203                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10204                         END_PROFILE(SMBtrans2);
10205                         return;
10206                 }
10207         }
10208
10209         if ((dscnt > state->total_data) || (pscnt > state->total_param))
10210                 goto bad_param;
10211
10212         if (state->total_data) {
10213
10214                 if (trans_oob(state->total_data, 0, dscnt)
10215                     || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
10216                         goto bad_param;
10217                 }
10218
10219                 /* Can't use talloc here, the core routines do realloc on the
10220                  * params and data. */
10221                 state->data = (char *)SMB_MALLOC(state->total_data);
10222                 if (state->data == NULL) {
10223                         DEBUG(0,("reply_trans2: data malloc fail for %u "
10224                                  "bytes !\n", (unsigned int)state->total_data));
10225                         TALLOC_FREE(state);
10226                         reply_nterror(req, NT_STATUS_NO_MEMORY);
10227                         END_PROFILE(SMBtrans2);
10228                         return;
10229                 }
10230
10231                 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
10232         }
10233
10234         if (state->total_param) {
10235
10236                 if (trans_oob(state->total_param, 0, pscnt)
10237                     || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
10238                         goto bad_param;
10239                 }
10240
10241                 /* Can't use talloc here, the core routines do realloc on the
10242                  * params and data. */
10243                 state->param = (char *)SMB_MALLOC(state->total_param);
10244                 if (state->param == NULL) {
10245                         DEBUG(0,("reply_trans: param malloc fail for %u "
10246                                  "bytes !\n", (unsigned int)state->total_param));
10247                         SAFE_FREE(state->data);
10248                         TALLOC_FREE(state);
10249                         reply_nterror(req, NT_STATUS_NO_MEMORY);
10250                         END_PROFILE(SMBtrans2);
10251                         return;
10252                 } 
10253
10254                 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
10255         }
10256
10257         state->received_data  = dscnt;
10258         state->received_param = pscnt;
10259
10260         if ((state->received_param == state->total_param) &&
10261             (state->received_data == state->total_data)) {
10262
10263                 handle_trans2(conn, req, state);
10264
10265                 SAFE_FREE(state->data);
10266                 SAFE_FREE(state->param);
10267                 TALLOC_FREE(state);
10268                 END_PROFILE(SMBtrans2);
10269                 return;
10270         }
10271
10272         DLIST_ADD(conn->pending_trans, state);
10273
10274         /* We need to send an interim response then receive the rest
10275            of the parameter/data bytes */
10276         reply_outbuf(req, 0, 0);
10277         show_msg((char *)req->outbuf);
10278         END_PROFILE(SMBtrans2);
10279         return;
10280
10281   bad_param:
10282
10283         DEBUG(0,("reply_trans2: invalid trans parameters\n"));
10284         SAFE_FREE(state->data);
10285         SAFE_FREE(state->param);
10286         TALLOC_FREE(state);
10287         END_PROFILE(SMBtrans2);
10288         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10289 }
10290
10291
10292 /****************************************************************************
10293  Reply to a SMBtranss2
10294  ****************************************************************************/
10295
10296 void reply_transs2(struct smb_request *req)
10297 {
10298         connection_struct *conn = req->conn;
10299         unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
10300         struct trans_state *state;
10301
10302         START_PROFILE(SMBtranss2);
10303
10304         show_msg((const char *)req->inbuf);
10305
10306         /* Windows clients expect all replies to
10307            a transact secondary (SMBtranss2 0x33)
10308            to have a command code of transact
10309            (SMBtrans2 0x32). See bug #8989
10310            and also [MS-CIFS] section 2.2.4.47.2
10311            for details.
10312         */
10313         req->cmd = SMBtrans2;
10314
10315         if (req->wct < 8) {
10316                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10317                 END_PROFILE(SMBtranss2);
10318                 return;
10319         }
10320
10321         for (state = conn->pending_trans; state != NULL;
10322              state = state->next) {
10323                 if (state->mid == req->mid) {
10324                         break;
10325                 }
10326         }
10327
10328         if ((state == NULL) || (state->cmd != SMBtrans2)) {
10329                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10330                 END_PROFILE(SMBtranss2);
10331                 return;
10332         }
10333
10334         /* Revise state->total_param and state->total_data in case they have
10335            changed downwards */
10336
10337         if (SVAL(req->vwv+0, 0) < state->total_param)
10338                 state->total_param = SVAL(req->vwv+0, 0);
10339         if (SVAL(req->vwv+1, 0) < state->total_data)
10340                 state->total_data = SVAL(req->vwv+1, 0);
10341
10342         pcnt = SVAL(req->vwv+2, 0);
10343         poff = SVAL(req->vwv+3, 0);
10344         pdisp = SVAL(req->vwv+4, 0);
10345
10346         dcnt = SVAL(req->vwv+5, 0);
10347         doff = SVAL(req->vwv+6, 0);
10348         ddisp = SVAL(req->vwv+7, 0);
10349
10350         state->received_param += pcnt;
10351         state->received_data += dcnt;
10352
10353         if ((state->received_data > state->total_data) ||
10354             (state->received_param > state->total_param))
10355                 goto bad_param;
10356
10357         if (pcnt) {
10358                 if (trans_oob(state->total_param, pdisp, pcnt)
10359                     || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
10360                         goto bad_param;
10361                 }
10362                 memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
10363         }
10364
10365         if (dcnt) {
10366                 if (trans_oob(state->total_data, ddisp, dcnt)
10367                     || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
10368                         goto bad_param;
10369                 }
10370                 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
10371         }
10372
10373         if ((state->received_param < state->total_param) ||
10374             (state->received_data < state->total_data)) {
10375                 END_PROFILE(SMBtranss2);
10376                 return;
10377         }
10378
10379         handle_trans2(conn, req, state);
10380
10381         DLIST_REMOVE(conn->pending_trans, state);
10382         SAFE_FREE(state->data);
10383         SAFE_FREE(state->param);
10384         TALLOC_FREE(state);
10385
10386         END_PROFILE(SMBtranss2);
10387         return;
10388
10389   bad_param:
10390
10391         DEBUG(0,("reply_transs2: invalid trans parameters\n"));
10392         DLIST_REMOVE(conn->pending_trans, state);
10393         SAFE_FREE(state->data);
10394         SAFE_FREE(state->param);
10395         TALLOC_FREE(state);
10396         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10397         END_PROFILE(SMBtranss2);
10398         return;
10399 }