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