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