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