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