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