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