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