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