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