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