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