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