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