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