smbd: Convert smb_set_file_dosmode to synthetic_smb_fname
[samba.git] / source3 / smbd / trans2.c
1 /*
2    Unix SMB/CIFS implementation.
3    SMB transaction2 handling
4    Copyright (C) Jeremy Allison                 1994-2007
5    Copyright (C) Stefan (metze) Metzmacher      2003
6    Copyright (C) Volker Lendecke                2005-2007
7    Copyright (C) Steve French                   2005
8    Copyright (C) James Peach                    2006-2007
9
10    Extensively modified by Andrew Tridgell, 1995
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 3 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include "includes.h"
27 #include "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                 status = create_synthetic_smb_fname(talloc_tos(),
6198                     fsp->base_fsp->fsp_name->base_name, newname, NULL,
6199                     &smb_fname_dst);
6200                 if (!NT_STATUS_IS_OK(status)) {
6201                         goto out;
6202                 }
6203
6204                 /*
6205                  * Set the original last component, since
6206                  * rename_internals_fsp() requires it.
6207                  */
6208                 smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
6209                                                               newname);
6210                 if (smb_fname_dst->original_lcomp == NULL) {
6211                         status = NT_STATUS_NO_MEMORY;
6212                         goto out;
6213                 }
6214
6215         }
6216
6217         DEBUG(10,("smb2_file_rename_information: "
6218                   "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
6219                   fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
6220                   smb_fname_str_dbg(smb_fname_dst)));
6221         status = rename_internals_fsp(conn, fsp, smb_fname_dst,
6222                                 (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM),
6223                                 overwrite);
6224
6225  out:
6226         TALLOC_FREE(smb_fname_dst);
6227         return status;
6228 }
6229
6230 static NTSTATUS smb_file_link_information(connection_struct *conn,
6231                                             struct smb_request *req,
6232                                             const char *pdata,
6233                                             int total_data,
6234                                             files_struct *fsp,
6235                                             struct smb_filename *smb_fname_src)
6236 {
6237         bool overwrite;
6238         uint32_t len;
6239         char *newname = NULL;
6240         struct smb_filename *smb_fname_dst = NULL;
6241         NTSTATUS status = NT_STATUS_OK;
6242         TALLOC_CTX *ctx = talloc_tos();
6243
6244         if (!fsp) {
6245                 return NT_STATUS_INVALID_HANDLE;
6246         }
6247
6248         if (total_data < 20) {
6249                 return NT_STATUS_INVALID_PARAMETER;
6250         }
6251
6252         overwrite = (CVAL(pdata,0) ? true : false);
6253         len = IVAL(pdata,16);
6254
6255         if (len > (total_data - 20) || (len == 0)) {
6256                 return NT_STATUS_INVALID_PARAMETER;
6257         }
6258
6259         srvstr_get_path(ctx, pdata, req->flags2, &newname,
6260                                 &pdata[20], len, STR_TERMINATE,
6261                                 &status);
6262         if (!NT_STATUS_IS_OK(status)) {
6263                 return status;
6264         }
6265
6266         DEBUG(10,("smb_file_link_information: got name |%s|\n",
6267                                 newname));
6268
6269         status = filename_convert(ctx,
6270                                 conn,
6271                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
6272                                 newname,
6273                                 UCF_SAVE_LCOMP,
6274                                 NULL,
6275                                 &smb_fname_dst);
6276         if (!NT_STATUS_IS_OK(status)) {
6277                 return status;
6278         }
6279
6280         if (fsp->base_fsp) {
6281                 /* No stream names. */
6282                 return NT_STATUS_NOT_SUPPORTED;
6283         }
6284
6285         DEBUG(10,("smb_file_link_information: "
6286                   "SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
6287                   fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
6288                   smb_fname_str_dbg(smb_fname_dst)));
6289         status = hardlink_internals(ctx,
6290                                 conn,
6291                                 req,
6292                                 overwrite,
6293                                 fsp->fsp_name,
6294                                 smb_fname_dst);
6295
6296         TALLOC_FREE(smb_fname_dst);
6297         return status;
6298 }
6299
6300 /****************************************************************************
6301  Deal with SMB_FILE_RENAME_INFORMATION.
6302 ****************************************************************************/
6303
6304 static NTSTATUS smb_file_rename_information(connection_struct *conn,
6305                                             struct smb_request *req,
6306                                             const char *pdata,
6307                                             int total_data,
6308                                             files_struct *fsp,
6309                                             struct smb_filename *smb_fname_src)
6310 {
6311         bool overwrite;
6312         uint32 root_fid;
6313         uint32 len;
6314         char *newname = NULL;
6315         struct smb_filename *smb_fname_dst = NULL;
6316         bool dest_has_wcard = False;
6317         NTSTATUS status = NT_STATUS_OK;
6318         char *p;
6319         TALLOC_CTX *ctx = talloc_tos();
6320
6321         if (total_data < 13) {
6322                 return NT_STATUS_INVALID_PARAMETER;
6323         }
6324
6325         overwrite = (CVAL(pdata,0) ? True : False);
6326         root_fid = IVAL(pdata,4);
6327         len = IVAL(pdata,8);
6328
6329         if (len > (total_data - 12) || (len == 0) || (root_fid != 0)) {
6330                 return NT_STATUS_INVALID_PARAMETER;
6331         }
6332
6333         srvstr_get_path_wcard(ctx, pdata, req->flags2, &newname, &pdata[12],
6334                               len, 0, &status,
6335                               &dest_has_wcard);
6336         if (!NT_STATUS_IS_OK(status)) {
6337                 return status;
6338         }
6339
6340         DEBUG(10,("smb_file_rename_information: got name |%s|\n",
6341                                 newname));
6342
6343         status = resolve_dfspath_wcard(ctx, conn,
6344                                        req->flags2 & FLAGS2_DFS_PATHNAMES,
6345                                        newname,
6346                                        true,
6347                                        !conn->sconn->using_smb2,
6348                                        &newname,
6349                                        &dest_has_wcard);
6350         if (!NT_STATUS_IS_OK(status)) {
6351                 return status;
6352         }
6353
6354         /* Check the new name has no '/' characters. */
6355         if (strchr_m(newname, '/')) {
6356                 return NT_STATUS_NOT_SUPPORTED;
6357         }
6358
6359         if (fsp && fsp->base_fsp) {
6360                 /* newname must be a stream name. */
6361                 if (newname[0] != ':') {
6362                         return NT_STATUS_NOT_SUPPORTED;
6363                 }
6364
6365                 /* Create an smb_fname to call rename_internals_fsp() with. */
6366                 status = create_synthetic_smb_fname(talloc_tos(),
6367                     fsp->base_fsp->fsp_name->base_name, newname, NULL,
6368                     &smb_fname_dst);
6369                 if (!NT_STATUS_IS_OK(status)) {
6370                         goto out;
6371                 }
6372
6373                 /*
6374                  * Set the original last component, since
6375                  * rename_internals_fsp() requires it.
6376                  */
6377                 smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
6378                                                               newname);
6379                 if (smb_fname_dst->original_lcomp == NULL) {
6380                         status = NT_STATUS_NO_MEMORY;
6381                         goto out;
6382                 }
6383
6384         } else {
6385                 /*
6386                  * Build up an smb_fname_dst based on the filename passed in.
6387                  * We basically just strip off the last component, and put on
6388                  * the newname instead.
6389                  */
6390                 char *base_name = NULL;
6391
6392                 /* newname must *not* be a stream name. */
6393                 if (newname[0] == ':') {
6394                         return NT_STATUS_NOT_SUPPORTED;
6395                 }
6396
6397                 /*
6398                  * Strip off the last component (filename) of the path passed
6399                  * in.
6400                  */
6401                 base_name = talloc_strdup(ctx, smb_fname_src->base_name);
6402                 if (!base_name) {
6403                         return NT_STATUS_NO_MEMORY;
6404                 }
6405                 p = strrchr_m(base_name, '/');
6406                 if (p) {
6407                         p[1] = '\0';
6408                 } else {
6409                         base_name = talloc_strdup(ctx, "");
6410                         if (!base_name) {
6411                                 return NT_STATUS_NO_MEMORY;
6412                         }
6413                 }
6414                 /* Append the new name. */
6415                 base_name = talloc_asprintf_append(base_name,
6416                                 "%s",
6417                                 newname);
6418                 if (!base_name) {
6419                         return NT_STATUS_NO_MEMORY;
6420                 }
6421
6422                 status = unix_convert(ctx, conn, base_name, &smb_fname_dst,
6423                                       (UCF_SAVE_LCOMP |
6424                                           (dest_has_wcard ?
6425                                               UCF_ALWAYS_ALLOW_WCARD_LCOMP :
6426                                               0)));
6427
6428                 /* If an error we expect this to be
6429                  * NT_STATUS_OBJECT_PATH_NOT_FOUND */
6430
6431                 if (!NT_STATUS_IS_OK(status)) {
6432                         if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND,
6433                                             status)) {
6434                                 goto out;
6435                         }
6436                         /* Create an smb_fname to call rename_internals_fsp() */
6437                         status = create_synthetic_smb_fname(ctx,
6438                                                             base_name, NULL,
6439                                                             NULL,
6440                                                             &smb_fname_dst);
6441                         if (!NT_STATUS_IS_OK(status)) {
6442                                 goto out;
6443                         }
6444                 }
6445         }
6446
6447         if (fsp) {
6448                 DEBUG(10,("smb_file_rename_information: "
6449                           "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
6450                           fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
6451                           smb_fname_str_dbg(smb_fname_dst)));
6452                 status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
6453                                               overwrite);
6454         } else {
6455                 DEBUG(10,("smb_file_rename_information: "
6456                           "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
6457                           smb_fname_str_dbg(smb_fname_src),
6458                           smb_fname_str_dbg(smb_fname_dst)));
6459                 status = rename_internals(ctx, conn, req, smb_fname_src,
6460                                           smb_fname_dst, 0, overwrite, false,
6461                                           dest_has_wcard,
6462                                           FILE_WRITE_ATTRIBUTES);
6463         }
6464  out:
6465         TALLOC_FREE(smb_fname_dst);
6466         return status;
6467 }
6468
6469 /****************************************************************************
6470  Deal with SMB_SET_POSIX_ACL.
6471 ****************************************************************************/
6472
6473 #if defined(HAVE_POSIX_ACLS)
6474 static NTSTATUS smb_set_posix_acl(connection_struct *conn,
6475                                 const char *pdata,
6476                                 int total_data,
6477                                 files_struct *fsp,
6478                                 const struct smb_filename *smb_fname)
6479 {
6480         uint16 posix_acl_version;
6481         uint16 num_file_acls;
6482         uint16 num_def_acls;
6483         bool valid_file_acls = True;
6484         bool valid_def_acls = True;
6485
6486         if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
6487                 return NT_STATUS_INVALID_PARAMETER;
6488         }
6489         posix_acl_version = SVAL(pdata,0);
6490         num_file_acls = SVAL(pdata,2);
6491         num_def_acls = SVAL(pdata,4);
6492
6493         if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
6494                 valid_file_acls = False;
6495                 num_file_acls = 0;
6496         }
6497
6498         if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
6499                 valid_def_acls = False;
6500                 num_def_acls = 0;
6501         }
6502
6503         if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
6504                 return NT_STATUS_INVALID_PARAMETER;
6505         }
6506
6507         if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
6508                         (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
6509                 return NT_STATUS_INVALID_PARAMETER;
6510         }
6511
6512         DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
6513                 smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp),
6514                 (unsigned int)num_file_acls,
6515                 (unsigned int)num_def_acls));
6516
6517         if (valid_file_acls && !set_unix_posix_acl(conn, fsp,
6518                 smb_fname->base_name, num_file_acls,
6519                 pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
6520                 return map_nt_error_from_unix(errno);
6521         }
6522
6523         if (valid_def_acls && !set_unix_posix_default_acl(conn,
6524                 smb_fname->base_name, &smb_fname->st, num_def_acls,
6525                 pdata + SMB_POSIX_ACL_HEADER_SIZE +
6526                 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
6527                 return map_nt_error_from_unix(errno);
6528         }
6529         return NT_STATUS_OK;
6530 }
6531 #endif
6532
6533 /****************************************************************************
6534  Deal with SMB_SET_POSIX_LOCK.
6535 ****************************************************************************/
6536
6537 static NTSTATUS smb_set_posix_lock(connection_struct *conn,
6538                                 struct smb_request *req,
6539                                 const char *pdata,
6540                                 int total_data,
6541                                 files_struct *fsp)
6542 {
6543         uint64_t count;
6544         uint64_t offset;
6545         uint64_t smblctx;
6546         bool blocking_lock = False;
6547         enum brl_type lock_type;
6548
6549         NTSTATUS status = NT_STATUS_OK;
6550
6551         if (fsp == NULL || fsp->fh->fd == -1) {
6552                 return NT_STATUS_INVALID_HANDLE;
6553         }
6554
6555         if (total_data != POSIX_LOCK_DATA_SIZE) {
6556                 return NT_STATUS_INVALID_PARAMETER;
6557         }
6558
6559         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
6560                 case POSIX_LOCK_TYPE_READ:
6561                         lock_type = READ_LOCK;
6562                         break;
6563                 case POSIX_LOCK_TYPE_WRITE:
6564                         /* Return the right POSIX-mappable error code for files opened read-only. */
6565                         if (!fsp->can_write) {
6566                                 return NT_STATUS_INVALID_HANDLE;
6567                         }
6568                         lock_type = WRITE_LOCK;
6569                         break;
6570                 case POSIX_LOCK_TYPE_UNLOCK:
6571                         lock_type = UNLOCK_LOCK;
6572                         break;
6573                 default:
6574                         return NT_STATUS_INVALID_PARAMETER;
6575         }
6576
6577         if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_NOWAIT) {
6578                 blocking_lock = False;
6579         } else if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_WAIT) {
6580                 blocking_lock = True;
6581         } else {
6582                 return NT_STATUS_INVALID_PARAMETER;
6583         }
6584
6585         if (!lp_blocking_locks(SNUM(conn))) { 
6586                 blocking_lock = False;
6587         }
6588
6589         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
6590 #if defined(HAVE_LONGLONG)
6591         offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
6592                         ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
6593         count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
6594                         ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
6595 #else /* HAVE_LONGLONG */
6596         offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET);
6597         count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
6598 #endif /* HAVE_LONGLONG */
6599
6600         DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
6601                         "smblctx = %llu, count = %.0f, offset = %.0f\n",
6602                 fsp_str_dbg(fsp),
6603                 (unsigned int)lock_type,
6604                 (unsigned long long)smblctx,
6605                 (double)count,
6606                 (double)offset ));
6607
6608         if (lock_type == UNLOCK_LOCK) {
6609                 status = do_unlock(req->sconn->msg_ctx,
6610                                 fsp,
6611                                 smblctx,
6612                                 count,
6613                                 offset,
6614                                 POSIX_LOCK);
6615         } else {
6616                 uint64_t block_smblctx;
6617
6618                 struct byte_range_lock *br_lck = do_lock(req->sconn->msg_ctx,
6619                                                         fsp,
6620                                                         smblctx,
6621                                                         count,
6622                                                         offset,
6623                                                         lock_type,
6624                                                         POSIX_LOCK,
6625                                                         blocking_lock,
6626                                                         &status,
6627                                                         &block_smblctx,
6628                                                         NULL);
6629
6630                 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
6631                         /*
6632                          * A blocking lock was requested. Package up
6633                          * this smb into a queued request and push it
6634                          * onto the blocking lock queue.
6635                          */
6636                         if(push_blocking_lock_request(br_lck,
6637                                                 req,
6638                                                 fsp,
6639                                                 -1, /* infinite timeout. */
6640                                                 0,
6641                                                 smblctx,
6642                                                 lock_type,
6643                                                 POSIX_LOCK,
6644                                                 offset,
6645                                                 count,
6646                                                 block_smblctx)) {
6647                                 TALLOC_FREE(br_lck);
6648                                 return status;
6649                         }
6650                 }
6651                 TALLOC_FREE(br_lck);
6652         }
6653
6654         return status;
6655 }
6656
6657 /****************************************************************************
6658  Deal with SMB_SET_FILE_BASIC_INFO.
6659 ****************************************************************************/
6660
6661 static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
6662                                         const char *pdata,
6663                                         int total_data,
6664                                         files_struct *fsp,
6665                                         const struct smb_filename *smb_fname)
6666 {
6667         /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
6668         struct smb_file_time ft;
6669         uint32 dosmode = 0;
6670         NTSTATUS status = NT_STATUS_OK;
6671
6672         ZERO_STRUCT(ft);
6673
6674         if (total_data < 36) {
6675                 return NT_STATUS_INVALID_PARAMETER;
6676         }
6677
6678         status = check_access(conn, fsp, smb_fname, FILE_WRITE_ATTRIBUTES);
6679         if (!NT_STATUS_IS_OK(status)) {
6680                 return status;
6681         }
6682
6683         /* Set the attributes */
6684         dosmode = IVAL(pdata,32);
6685         status = smb_set_file_dosmode(conn, smb_fname, dosmode);
6686         if (!NT_STATUS_IS_OK(status)) {
6687                 return status;
6688         }
6689
6690         /* create time */
6691         ft.create_time = interpret_long_date(pdata);
6692
6693         /* access time */
6694         ft.atime = interpret_long_date(pdata+8);
6695
6696         /* write time. */
6697         ft.mtime = interpret_long_date(pdata+16);
6698
6699         /* change time. */
6700         ft.ctime = interpret_long_date(pdata+24);
6701
6702         DEBUG(10, ("smb_set_file_basic_info: file %s\n",
6703                    smb_fname_str_dbg(smb_fname)));
6704
6705         return smb_set_file_time(conn, fsp, smb_fname, &ft,
6706                                  true);
6707 }
6708
6709 /****************************************************************************
6710  Deal with SMB_INFO_STANDARD.
6711 ****************************************************************************/
6712
6713 static NTSTATUS smb_set_info_standard(connection_struct *conn,
6714                                         const char *pdata,
6715                                         int total_data,
6716                                         files_struct *fsp,
6717                                         const struct smb_filename *smb_fname)
6718 {
6719         NTSTATUS status;
6720         struct smb_file_time ft;
6721
6722         ZERO_STRUCT(ft);
6723
6724         if (total_data < 12) {
6725                 return NT_STATUS_INVALID_PARAMETER;
6726         }
6727
6728         /* create time */
6729         ft.create_time = convert_time_t_to_timespec(srv_make_unix_date2(pdata));
6730         /* access time */
6731         ft.atime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+4));
6732         /* write time */
6733         ft.mtime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+8));
6734
6735         DEBUG(10,("smb_set_info_standard: file %s\n",
6736                 smb_fname_str_dbg(smb_fname)));
6737
6738         status = check_access(conn, fsp, smb_fname, FILE_WRITE_ATTRIBUTES);
6739         if (!NT_STATUS_IS_OK(status)) {
6740                 return status;
6741         }
6742
6743         return smb_set_file_time(conn,
6744                                 fsp,
6745                                 smb_fname,
6746                                 &ft,
6747                                 true);
6748 }
6749
6750 /****************************************************************************
6751  Deal with SMB_SET_FILE_ALLOCATION_INFO.
6752 ****************************************************************************/
6753
6754 static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
6755                                              struct smb_request *req,
6756                                         const char *pdata,
6757                                         int total_data,
6758                                         files_struct *fsp,
6759                                         struct smb_filename *smb_fname)
6760 {
6761         uint64_t allocation_size = 0;
6762         NTSTATUS status = NT_STATUS_OK;
6763         files_struct *new_fsp = NULL;
6764
6765         if (!VALID_STAT(smb_fname->st)) {
6766                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6767         }
6768
6769         if (total_data < 8) {
6770                 return NT_STATUS_INVALID_PARAMETER;
6771         }
6772
6773         allocation_size = (uint64_t)IVAL(pdata,0);
6774         allocation_size |= (((uint64_t)IVAL(pdata,4)) << 32);
6775         DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
6776                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
6777                   (double)allocation_size));
6778
6779         if (allocation_size) {
6780                 allocation_size = smb_roundup(conn, allocation_size);
6781         }
6782
6783         DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
6784                   "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname),
6785                   (double)allocation_size));
6786
6787         if (fsp && fsp->fh->fd != -1) {
6788                 /* Open file handle. */
6789                 if (!(fsp->access_mask & FILE_WRITE_DATA)) {
6790                         return NT_STATUS_ACCESS_DENIED;
6791                 }
6792
6793                 /* Only change if needed. */
6794                 if (allocation_size != get_file_size_stat(&smb_fname->st)) {
6795                         if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
6796                                 return map_nt_error_from_unix(errno);
6797                         }
6798                 }
6799                 /* But always update the time. */
6800                 /*
6801                  * This is equivalent to a write. Ensure it's seen immediately
6802                  * if there are no pending writes.
6803                  */
6804                 trigger_write_time_update_immediate(fsp);
6805                 return NT_STATUS_OK;
6806         }
6807
6808         /* Pathname or stat or directory file. */
6809         status = SMB_VFS_CREATE_FILE(
6810                 conn,                                   /* conn */
6811                 req,                                    /* req */
6812                 0,                                      /* root_dir_fid */
6813                 smb_fname,                              /* fname */
6814                 FILE_WRITE_DATA,                        /* access_mask */
6815                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
6816                     FILE_SHARE_DELETE),
6817                 FILE_OPEN,                              /* create_disposition*/
6818                 0,                                      /* create_options */
6819                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
6820                 FORCE_OPLOCK_BREAK_TO_NONE,             /* oplock_request */
6821                 0,                                      /* allocation_size */
6822                 0,                                      /* private_flags */
6823                 NULL,                                   /* sd */
6824                 NULL,                                   /* ea_list */
6825                 &new_fsp,                               /* result */
6826                 NULL);                                  /* pinfo */
6827
6828         if (!NT_STATUS_IS_OK(status)) {
6829                 /* NB. We check for open_was_deferred in the caller. */
6830                 return status;
6831         }
6832
6833         /* Only change if needed. */
6834         if (allocation_size != get_file_size_stat(&smb_fname->st)) {
6835                 if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
6836                         status = map_nt_error_from_unix(errno);
6837                         close_file(req, new_fsp, NORMAL_CLOSE);
6838                         return status;
6839                 }
6840         }
6841
6842         /* Changing the allocation size should set the last mod time. */
6843         /*
6844          * This is equivalent to a write. Ensure it's seen immediately
6845          * if there are no pending writes.
6846          */
6847         trigger_write_time_update_immediate(new_fsp);
6848
6849         close_file(req, new_fsp, NORMAL_CLOSE);
6850         return NT_STATUS_OK;
6851 }
6852
6853 /****************************************************************************
6854  Deal with SMB_SET_FILE_END_OF_FILE_INFO.
6855 ****************************************************************************/
6856
6857 static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
6858                                               struct smb_request *req,
6859                                         const char *pdata,
6860                                         int total_data,
6861                                         files_struct *fsp,
6862                                         const struct smb_filename *smb_fname,
6863                                         bool fail_after_createfile)
6864 {
6865         off_t size;
6866
6867         if (total_data < 8) {
6868                 return NT_STATUS_INVALID_PARAMETER;
6869         }
6870
6871         size = IVAL(pdata,0);
6872         size |= (((off_t)IVAL(pdata,4)) << 32);
6873         DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
6874                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
6875                   (double)size));
6876
6877         return smb_set_file_size(conn, req,
6878                                 fsp,
6879                                 smb_fname,
6880                                 &smb_fname->st,
6881                                 size,
6882                                 fail_after_createfile);
6883 }
6884
6885 /****************************************************************************
6886  Allow a UNIX info mknod.
6887 ****************************************************************************/
6888
6889 static NTSTATUS smb_unix_mknod(connection_struct *conn,
6890                                         const char *pdata,
6891                                         int total_data,
6892                                         const struct smb_filename *smb_fname)
6893 {
6894         uint32 file_type = IVAL(pdata,56);
6895 #if defined(HAVE_MAKEDEV)
6896         uint32 dev_major = IVAL(pdata,60);
6897         uint32 dev_minor = IVAL(pdata,68);
6898 #endif
6899         SMB_DEV_T dev = (SMB_DEV_T)0;
6900         uint32 raw_unixmode = IVAL(pdata,84);
6901         NTSTATUS status;
6902         mode_t unixmode;
6903
6904         if (total_data < 100) {
6905                 return NT_STATUS_INVALID_PARAMETER;
6906         }
6907
6908         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
6909                                       PERM_NEW_FILE, &unixmode);
6910         if (!NT_STATUS_IS_OK(status)) {
6911                 return status;
6912         }
6913
6914 #if defined(HAVE_MAKEDEV)
6915         dev = makedev(dev_major, dev_minor);
6916 #endif
6917
6918         switch (file_type) {
6919 #if defined(S_IFIFO)
6920                 case UNIX_TYPE_FIFO:
6921                         unixmode |= S_IFIFO;
6922                         break;
6923 #endif
6924 #if defined(S_IFSOCK)
6925                 case UNIX_TYPE_SOCKET:
6926                         unixmode |= S_IFSOCK;
6927                         break;
6928 #endif
6929 #if defined(S_IFCHR)
6930                 case UNIX_TYPE_CHARDEV:
6931                         unixmode |= S_IFCHR;
6932                         break;
6933 #endif
6934 #if defined(S_IFBLK)
6935                 case UNIX_TYPE_BLKDEV:
6936                         unixmode |= S_IFBLK;
6937                         break;
6938 #endif
6939                 default:
6940                         return NT_STATUS_INVALID_PARAMETER;
6941         }
6942
6943         DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
6944                   "%.0f mode 0%o for file %s\n", (double)dev,
6945                   (unsigned int)unixmode, smb_fname_str_dbg(smb_fname)));
6946
6947         /* Ok - do the mknod. */
6948         if (SMB_VFS_MKNOD(conn, smb_fname->base_name, unixmode, dev) != 0) {
6949                 return map_nt_error_from_unix(errno);
6950         }
6951
6952         /* If any of the other "set" calls fail we
6953          * don't want to end up with a half-constructed mknod.
6954          */
6955
6956         if (lp_inherit_perms(SNUM(conn))) {
6957                 char *parent;
6958                 if (!parent_dirname(talloc_tos(), smb_fname->base_name,
6959                                     &parent, NULL)) {
6960                         return NT_STATUS_NO_MEMORY;
6961                 }
6962                 inherit_access_posix_acl(conn, parent, smb_fname->base_name,
6963                                          unixmode);
6964                 TALLOC_FREE(parent);
6965         }
6966
6967         return NT_STATUS_OK;
6968 }
6969
6970 /****************************************************************************
6971  Deal with SMB_SET_FILE_UNIX_BASIC.
6972 ****************************************************************************/
6973
6974 static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
6975                                         struct smb_request *req,
6976                                         const char *pdata,
6977                                         int total_data,
6978                                         files_struct *fsp,
6979                                         const struct smb_filename *smb_fname)
6980 {
6981         struct smb_file_time ft;
6982         uint32 raw_unixmode;
6983         mode_t unixmode;
6984         off_t size = 0;
6985         uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
6986         gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
6987         NTSTATUS status = NT_STATUS_OK;
6988         bool delete_on_fail = False;
6989         enum perm_type ptype;
6990         files_struct *all_fsps = NULL;
6991         bool modify_mtime = true;
6992         struct file_id id;
6993         struct smb_filename *smb_fname_tmp = NULL;
6994         SMB_STRUCT_STAT sbuf;
6995
6996         ZERO_STRUCT(ft);
6997
6998         if (total_data < 100) {
6999                 return NT_STATUS_INVALID_PARAMETER;
7000         }
7001
7002         if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
7003            IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
7004                 size=IVAL(pdata,0); /* first 8 Bytes are size */
7005                 size |= (((off_t)IVAL(pdata,4)) << 32);
7006         }
7007
7008         ft.atime = interpret_long_date(pdata+24); /* access_time */
7009         ft.mtime = interpret_long_date(pdata+32); /* modification_time */
7010         set_owner = (uid_t)IVAL(pdata,40);
7011         set_grp = (gid_t)IVAL(pdata,48);
7012         raw_unixmode = IVAL(pdata,84);
7013
7014         if (VALID_STAT(smb_fname->st)) {
7015                 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
7016                         ptype = PERM_EXISTING_DIR;
7017                 } else {
7018                         ptype = PERM_EXISTING_FILE;
7019                 }
7020         } else {
7021                 ptype = PERM_NEW_FILE;
7022         }
7023
7024         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
7025                                       ptype, &unixmode);
7026         if (!NT_STATUS_IS_OK(status)) {
7027                 return status;
7028         }
7029
7030         DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
7031                   "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
7032                   smb_fname_str_dbg(smb_fname), (double)size,
7033                   (unsigned int)set_owner, (unsigned int)set_grp,
7034                   (int)raw_unixmode));
7035
7036         sbuf = smb_fname->st;
7037
7038         if (!VALID_STAT(sbuf)) {
7039                 /*
7040                  * The only valid use of this is to create character and block
7041                  * devices, and named pipes. This is deprecated (IMHO) and 
7042                  * a new info level should be used for mknod. JRA.
7043                  */
7044
7045                 status = smb_unix_mknod(conn,
7046                                         pdata,
7047                                         total_data,
7048                                         smb_fname);
7049                 if (!NT_STATUS_IS_OK(status)) {
7050                         return status;
7051                 }
7052
7053                 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
7054                 if (smb_fname_tmp == NULL) {
7055                         return NT_STATUS_NO_MEMORY;
7056                 }
7057
7058                 if (SMB_VFS_STAT(conn, smb_fname_tmp) != 0) {
7059                         status = map_nt_error_from_unix(errno);
7060                         TALLOC_FREE(smb_fname_tmp);
7061                         SMB_VFS_UNLINK(conn, smb_fname);
7062                         return status;
7063                 }
7064
7065                 sbuf = smb_fname_tmp->st;
7066                 smb_fname = smb_fname_tmp;
7067
7068                 /* Ensure we don't try and change anything else. */
7069                 raw_unixmode = SMB_MODE_NO_CHANGE;
7070                 size = get_file_size_stat(&sbuf);
7071                 ft.atime = sbuf.st_ex_atime;
7072                 ft.mtime = sbuf.st_ex_mtime;
7073                 /* 
7074                  * We continue here as we might want to change the 
7075                  * owner uid/gid.
7076                  */
7077                 delete_on_fail = True;
7078         }
7079
7080 #if 1
7081         /* Horrible backwards compatibility hack as an old server bug
7082          * allowed a CIFS client bug to remain unnoticed :-(. JRA.
7083          * */
7084
7085         if (!size) {
7086                 size = get_file_size_stat(&sbuf);
7087         }
7088 #endif
7089
7090         /*
7091          * Deal with the UNIX specific mode set.
7092          */
7093
7094         if (raw_unixmode != SMB_MODE_NO_CHANGE) {
7095                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7096                           "setting mode 0%o for file %s\n",
7097                           (unsigned int)unixmode,
7098                           smb_fname_str_dbg(smb_fname)));
7099                 if (SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode) != 0) {
7100                         return map_nt_error_from_unix(errno);
7101                 }
7102         }
7103
7104         /*
7105          * Deal with the UNIX specific uid set.
7106          */
7107
7108         if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) &&
7109             (sbuf.st_ex_uid != set_owner)) {
7110                 int ret;
7111
7112                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7113                           "changing owner %u for path %s\n",
7114                           (unsigned int)set_owner,
7115                           smb_fname_str_dbg(smb_fname)));
7116
7117                 if (S_ISLNK(sbuf.st_ex_mode)) {
7118                         ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name,
7119                                              set_owner, (gid_t)-1);
7120                 } else {
7121                         ret = SMB_VFS_CHOWN(conn, smb_fname->base_name,
7122                                             set_owner, (gid_t)-1);
7123                 }
7124
7125                 if (ret != 0) {
7126                         status = map_nt_error_from_unix(errno);
7127                         if (delete_on_fail) {
7128                                 SMB_VFS_UNLINK(conn, smb_fname);
7129                         }
7130                         return status;
7131                 }
7132         }
7133
7134         /*
7135          * Deal with the UNIX specific gid set.
7136          */
7137
7138         if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) &&
7139             (sbuf.st_ex_gid != set_grp)) {
7140                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7141                           "changing group %u for file %s\n",
7142                           (unsigned int)set_owner,
7143                           smb_fname_str_dbg(smb_fname)));
7144                 if (SMB_VFS_CHOWN(conn, smb_fname->base_name, (uid_t)-1,
7145                                   set_grp) != 0) {
7146                         status = map_nt_error_from_unix(errno);
7147                         if (delete_on_fail) {
7148                                 SMB_VFS_UNLINK(conn, smb_fname);
7149                         }
7150                         return status;
7151                 }
7152         }
7153
7154         /* Deal with any size changes. */
7155
7156         status = smb_set_file_size(conn, req,
7157                                    fsp,
7158                                    smb_fname,
7159                                    &sbuf,
7160                                    size,
7161                                    false);
7162         if (!NT_STATUS_IS_OK(status)) {
7163                 return status;
7164         }
7165
7166         /* Deal with any time changes. */
7167         if (null_timespec(ft.mtime) && null_timespec(ft.atime)) {
7168                 /* No change, don't cancel anything. */
7169                 return status;
7170         }
7171
7172         id = vfs_file_id_from_sbuf(conn, &sbuf);
7173         for(all_fsps = file_find_di_first(conn->sconn, id); all_fsps;
7174                         all_fsps = file_find_di_next(all_fsps)) {
7175                 /*
7176                  * We're setting the time explicitly for UNIX.
7177                  * Cancel any pending changes over all handles.
7178                  */
7179                 all_fsps->update_write_time_on_close = false;
7180                 TALLOC_FREE(all_fsps->update_write_time_event);
7181         }
7182
7183         /*
7184          * Override the "setting_write_time"
7185          * parameter here as it almost does what
7186          * we need. Just remember if we modified
7187          * mtime and send the notify ourselves.
7188          */
7189         if (null_timespec(ft.mtime)) {
7190                 modify_mtime = false;
7191         }
7192
7193         status = smb_set_file_time(conn,
7194                                 fsp,
7195                                 smb_fname,
7196                                 &ft,
7197                                 false);
7198         if (modify_mtime) {
7199                 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
7200                         FILE_NOTIFY_CHANGE_LAST_WRITE, smb_fname->base_name);
7201         }
7202         return status;
7203 }
7204
7205 /****************************************************************************
7206  Deal with SMB_SET_FILE_UNIX_INFO2.
7207 ****************************************************************************/
7208
7209 static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
7210                                         struct smb_request *req,
7211                                         const char *pdata,
7212                                         int total_data,
7213                                         files_struct *fsp,
7214                                         const struct smb_filename *smb_fname)
7215 {
7216         NTSTATUS status;
7217         uint32 smb_fflags;
7218         uint32 smb_fmask;
7219
7220         if (total_data < 116) {
7221                 return NT_STATUS_INVALID_PARAMETER;
7222         }
7223
7224         /* Start by setting all the fields that are common between UNIX_BASIC
7225          * and UNIX_INFO2.
7226          */
7227         status = smb_set_file_unix_basic(conn, req, pdata, total_data,
7228                                          fsp, smb_fname);
7229         if (!NT_STATUS_IS_OK(status)) {
7230                 return status;
7231         }
7232
7233         smb_fflags = IVAL(pdata, 108);
7234         smb_fmask = IVAL(pdata, 112);
7235
7236         /* NB: We should only attempt to alter the file flags if the client
7237          * sends a non-zero mask.
7238          */
7239         if (smb_fmask != 0) {
7240                 int stat_fflags = 0;
7241
7242                 if (!map_info2_flags_to_sbuf(&smb_fname->st, smb_fflags,
7243                                              smb_fmask, &stat_fflags)) {
7244                         /* Client asked to alter a flag we don't understand. */
7245                         return NT_STATUS_INVALID_PARAMETER;
7246                 }
7247
7248                 if (fsp && fsp->fh->fd != -1) {
7249                         /* XXX: we should be  using SMB_VFS_FCHFLAGS here. */
7250                         return NT_STATUS_NOT_SUPPORTED;
7251                 } else {
7252                         if (SMB_VFS_CHFLAGS(conn, smb_fname->base_name,
7253                                             stat_fflags) != 0) {
7254                                 return map_nt_error_from_unix(errno);
7255                         }
7256                 }
7257         }
7258
7259         /* XXX: need to add support for changing the create_time here. You
7260          * can do this for paths on Darwin with setattrlist(2). The right way
7261          * to hook this up is probably by extending the VFS utimes interface.
7262          */
7263
7264         return NT_STATUS_OK;
7265 }
7266
7267 /****************************************************************************
7268  Create a directory with POSIX semantics.
7269 ****************************************************************************/
7270
7271 static NTSTATUS smb_posix_mkdir(connection_struct *conn,
7272                                 struct smb_request *req,
7273                                 char **ppdata,
7274                                 int total_data,
7275                                 struct smb_filename *smb_fname,
7276                                 int *pdata_return_size)
7277 {
7278         NTSTATUS status = NT_STATUS_OK;
7279         uint32 raw_unixmode = 0;
7280         uint32 mod_unixmode = 0;
7281         mode_t unixmode = (mode_t)0;
7282         files_struct *fsp = NULL;
7283         uint16 info_level_return = 0;
7284         int info;
7285         char *pdata = *ppdata;
7286
7287         if (total_data < 18) {
7288                 return NT_STATUS_INVALID_PARAMETER;
7289         }
7290
7291         raw_unixmode = IVAL(pdata,8);
7292         /* Next 4 bytes are not yet defined. */
7293
7294         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
7295                                       PERM_NEW_DIR, &unixmode);
7296         if (!NT_STATUS_IS_OK(status)) {
7297                 return status;
7298         }
7299
7300         mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
7301
7302         DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
7303                   smb_fname_str_dbg(smb_fname), (unsigned int)unixmode));
7304
7305         status = SMB_VFS_CREATE_FILE(
7306                 conn,                                   /* conn */
7307                 req,                                    /* req */
7308                 0,                                      /* root_dir_fid */
7309                 smb_fname,                              /* fname */
7310                 FILE_READ_ATTRIBUTES,                   /* access_mask */
7311                 FILE_SHARE_NONE,                        /* share_access */
7312                 FILE_CREATE,                            /* create_disposition*/
7313                 FILE_DIRECTORY_FILE,                    /* create_options */
7314                 mod_unixmode,                           /* file_attributes */
7315                 0,                                      /* oplock_request */
7316                 0,                                      /* allocation_size */
7317                 0,                                      /* private_flags */
7318                 NULL,                                   /* sd */
7319                 NULL,                                   /* ea_list */
7320                 &fsp,                                   /* result */
7321                 &info);                                 /* pinfo */
7322
7323         if (NT_STATUS_IS_OK(status)) {
7324                 close_file(req, fsp, NORMAL_CLOSE);
7325         }
7326
7327         info_level_return = SVAL(pdata,16);
7328  
7329         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
7330                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
7331         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
7332                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
7333         } else {
7334                 *pdata_return_size = 12;
7335         }
7336
7337         /* Realloc the data size */
7338         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
7339         if (*ppdata == NULL) {
7340                 *pdata_return_size = 0;
7341                 return NT_STATUS_NO_MEMORY;
7342         }
7343         pdata = *ppdata;
7344
7345         SSVAL(pdata,0,NO_OPLOCK_RETURN);
7346         SSVAL(pdata,2,0); /* No fnum. */
7347         SIVAL(pdata,4,info); /* Was directory created. */
7348
7349         switch (info_level_return) {
7350                 case SMB_QUERY_FILE_UNIX_BASIC:
7351                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
7352                         SSVAL(pdata,10,0); /* Padding. */
7353                         store_file_unix_basic(conn, pdata + 12, fsp,
7354                                               &smb_fname->st);
7355                         break;
7356                 case SMB_QUERY_FILE_UNIX_INFO2:
7357                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
7358                         SSVAL(pdata,10,0); /* Padding. */
7359                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
7360                                                     &smb_fname->st);
7361                         break;
7362                 default:
7363                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
7364                         SSVAL(pdata,10,0); /* Padding. */
7365                         break;
7366         }
7367
7368         return status;
7369 }
7370
7371 /****************************************************************************
7372  Open/Create a file with POSIX semantics.
7373 ****************************************************************************/
7374
7375 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
7376 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
7377
7378 static NTSTATUS smb_posix_open(connection_struct *conn,
7379                                struct smb_request *req,
7380                                 char **ppdata,
7381                                 int total_data,
7382                                 struct smb_filename *smb_fname,
7383                                 int *pdata_return_size)
7384 {
7385         bool extended_oplock_granted = False;
7386         char *pdata = *ppdata;
7387         uint32 flags = 0;
7388         uint32 wire_open_mode = 0;
7389         uint32 raw_unixmode = 0;
7390         uint32 mod_unixmode = 0;
7391         uint32 create_disp = 0;
7392         uint32 access_mask = 0;
7393         uint32 create_options = FILE_NON_DIRECTORY_FILE;
7394         NTSTATUS status = NT_STATUS_OK;
7395         mode_t unixmode = (mode_t)0;
7396         files_struct *fsp = NULL;
7397         int oplock_request = 0;
7398         int info = 0;
7399         uint16 info_level_return = 0;
7400
7401         if (total_data < 18) {
7402                 return NT_STATUS_INVALID_PARAMETER;
7403         }
7404
7405         flags = IVAL(pdata,0);
7406         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
7407         if (oplock_request) {
7408                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
7409         }
7410
7411         wire_open_mode = IVAL(pdata,4);
7412
7413         if (wire_open_mode == (SMB_O_CREAT|SMB_O_DIRECTORY)) {
7414                 return smb_posix_mkdir(conn, req,
7415                                         ppdata,
7416                                         total_data,
7417                                         smb_fname,
7418                                         pdata_return_size);
7419         }
7420
7421         switch (wire_open_mode & SMB_ACCMODE) {
7422                 case SMB_O_RDONLY:
7423                         access_mask = SMB_O_RDONLY_MAPPING;
7424                         break;
7425                 case SMB_O_WRONLY:
7426                         access_mask = SMB_O_WRONLY_MAPPING;
7427                         break;
7428                 case SMB_O_RDWR:
7429                         access_mask = (SMB_O_RDONLY_MAPPING|
7430                                         SMB_O_WRONLY_MAPPING);
7431                         break;
7432                 default:
7433                         DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
7434                                 (unsigned int)wire_open_mode ));
7435                         return NT_STATUS_INVALID_PARAMETER;
7436         }
7437
7438         wire_open_mode &= ~SMB_ACCMODE;
7439
7440         /* First take care of O_CREAT|O_EXCL interactions. */
7441         switch (wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) {
7442                 case (SMB_O_CREAT | SMB_O_EXCL):
7443                         /* File exists fail. File not exist create. */
7444                         create_disp = FILE_CREATE;
7445                         break;
7446                 case SMB_O_CREAT:
7447                         /* File exists open. File not exist create. */
7448                         create_disp = FILE_OPEN_IF;
7449                         break;
7450                 case SMB_O_EXCL:
7451                         /* O_EXCL on its own without O_CREAT is undefined.
7452                            We deliberately ignore it as some versions of
7453                            Linux CIFSFS can send a bare O_EXCL on the
7454                            wire which other filesystems in the kernel
7455                            ignore. See bug 9519 for details. */
7456
7457                         /* Fallthrough. */
7458
7459                 case 0:
7460                         /* File exists open. File not exist fail. */
7461                         create_disp = FILE_OPEN;
7462                         break;
7463                 default:
7464                         DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
7465                                 (unsigned int)wire_open_mode ));
7466                         return NT_STATUS_INVALID_PARAMETER;
7467         }
7468
7469         /* Next factor in the effects of O_TRUNC. */
7470         wire_open_mode &= ~(SMB_O_CREAT | SMB_O_EXCL);
7471
7472         if (wire_open_mode & SMB_O_TRUNC) {
7473                 switch (create_disp) {
7474                         case FILE_CREATE:
7475                                 /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
7476                                 /* Leave create_disp alone as
7477                                    (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
7478                                 */
7479                                 /* File exists fail. File not exist create. */
7480                                 break;
7481                         case FILE_OPEN_IF:
7482                                 /* SMB_O_CREAT | SMB_O_TRUNC */
7483                                 /* File exists overwrite. File not exist create. */
7484                                 create_disp = FILE_OVERWRITE_IF;
7485                                 break;
7486                         case FILE_OPEN:
7487                                 /* SMB_O_TRUNC */
7488                                 /* File exists overwrite. File not exist fail. */
7489                                 create_disp = FILE_OVERWRITE;
7490                                 break;
7491                         default:
7492                                 /* Cannot get here. */
7493                                 smb_panic("smb_posix_open: logic error");
7494                                 return NT_STATUS_INVALID_PARAMETER;
7495                 }
7496         }
7497
7498         raw_unixmode = IVAL(pdata,8);
7499         /* Next 4 bytes are not yet defined. */
7500
7501         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
7502                                       (VALID_STAT(smb_fname->st) ?
7503                                           PERM_EXISTING_FILE : PERM_NEW_FILE),
7504                                       &unixmode);
7505
7506         if (!NT_STATUS_IS_OK(status)) {
7507                 return status;
7508         }
7509
7510         mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
7511
7512         if (wire_open_mode & SMB_O_SYNC) {
7513                 create_options |= FILE_WRITE_THROUGH;
7514         }
7515         if (wire_open_mode & SMB_O_APPEND) {
7516                 access_mask |= FILE_APPEND_DATA;
7517         }
7518         if (wire_open_mode & SMB_O_DIRECT) {
7519                 mod_unixmode |= FILE_FLAG_NO_BUFFERING;
7520         }
7521
7522         if ((wire_open_mode & SMB_O_DIRECTORY) ||
7523                         VALID_STAT_OF_DIR(smb_fname->st)) {
7524                 if (access_mask != SMB_O_RDONLY_MAPPING) {
7525                         return NT_STATUS_FILE_IS_A_DIRECTORY;
7526                 }
7527                 create_options &= ~FILE_NON_DIRECTORY_FILE;
7528                 create_options |= FILE_DIRECTORY_FILE;
7529         }
7530
7531         DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
7532                 smb_fname_str_dbg(smb_fname),
7533                 (unsigned int)wire_open_mode,
7534                 (unsigned int)unixmode ));
7535
7536         status = SMB_VFS_CREATE_FILE(
7537                 conn,                                   /* conn */
7538                 req,                                    /* req */
7539                 0,                                      /* root_dir_fid */
7540                 smb_fname,                              /* fname */
7541                 access_mask,                            /* access_mask */
7542                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
7543                     FILE_SHARE_DELETE),
7544                 create_disp,                            /* create_disposition*/
7545                 create_options,                         /* create_options */
7546                 mod_unixmode,                           /* file_attributes */
7547                 oplock_request,                         /* oplock_request */
7548                 0,                                      /* allocation_size */
7549                 0,                                      /* private_flags */
7550                 NULL,                                   /* sd */
7551                 NULL,                                   /* ea_list */
7552                 &fsp,                                   /* result */
7553                 &info);                                 /* pinfo */
7554
7555         if (!NT_STATUS_IS_OK(status)) {
7556                 return status;
7557         }
7558
7559         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
7560                 extended_oplock_granted = True;
7561         }
7562
7563         if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
7564                 extended_oplock_granted = True;
7565         }
7566
7567         info_level_return = SVAL(pdata,16);
7568  
7569         /* Allocate the correct return size. */
7570
7571         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
7572                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
7573         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
7574                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
7575         } else {
7576                 *pdata_return_size = 12;
7577         }
7578
7579         /* Realloc the data size */
7580         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
7581         if (*ppdata == NULL) {
7582                 close_file(req, fsp, ERROR_CLOSE);
7583                 *pdata_return_size = 0;
7584                 return NT_STATUS_NO_MEMORY;
7585         }
7586         pdata = *ppdata;
7587
7588         if (extended_oplock_granted) {
7589                 if (flags & REQUEST_BATCH_OPLOCK) {
7590                         SSVAL(pdata,0, BATCH_OPLOCK_RETURN);
7591                 } else {
7592                         SSVAL(pdata,0, EXCLUSIVE_OPLOCK_RETURN);
7593                 }
7594         } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
7595                 SSVAL(pdata,0, LEVEL_II_OPLOCK_RETURN);
7596         } else {
7597                 SSVAL(pdata,0,NO_OPLOCK_RETURN);
7598         }
7599
7600         SSVAL(pdata,2,fsp->fnum);
7601         SIVAL(pdata,4,info); /* Was file created etc. */
7602
7603         switch (info_level_return) {
7604                 case SMB_QUERY_FILE_UNIX_BASIC:
7605                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
7606                         SSVAL(pdata,10,0); /* padding. */
7607                         store_file_unix_basic(conn, pdata + 12, fsp,
7608                                               &smb_fname->st);
7609                         break;
7610                 case SMB_QUERY_FILE_UNIX_INFO2:
7611                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
7612                         SSVAL(pdata,10,0); /* padding. */
7613                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
7614                                                     &smb_fname->st);
7615                         break;
7616                 default:
7617                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
7618                         SSVAL(pdata,10,0); /* padding. */
7619                         break;
7620         }
7621         return NT_STATUS_OK;
7622 }
7623
7624 /****************************************************************************
7625  Delete a file with POSIX semantics.
7626 ****************************************************************************/
7627
7628 static NTSTATUS smb_posix_unlink(connection_struct *conn,
7629                                  struct smb_request *req,
7630                                 const char *pdata,
7631                                 int total_data,
7632                                 struct smb_filename *smb_fname)
7633 {
7634         NTSTATUS status = NT_STATUS_OK;
7635         files_struct *fsp = NULL;
7636         uint16 flags = 0;
7637         char del = 1;
7638         int info = 0;
7639         int create_options = 0;
7640         int i;
7641         struct share_mode_lock *lck = NULL;
7642
7643         if (total_data < 2) {
7644                 return NT_STATUS_INVALID_PARAMETER;
7645         }
7646
7647         flags = SVAL(pdata,0);
7648
7649         if (!VALID_STAT(smb_fname->st)) {
7650                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
7651         }
7652
7653         if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
7654                         !VALID_STAT_OF_DIR(smb_fname->st)) {
7655                 return NT_STATUS_NOT_A_DIRECTORY;
7656         }
7657
7658         DEBUG(10,("smb_posix_unlink: %s %s\n",
7659                 (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
7660                 smb_fname_str_dbg(smb_fname)));
7661
7662         if (VALID_STAT_OF_DIR(smb_fname->st)) {
7663                 create_options |= FILE_DIRECTORY_FILE;
7664         }
7665
7666         status = SMB_VFS_CREATE_FILE(
7667                 conn,                                   /* conn */
7668                 req,                                    /* req */
7669                 0,                                      /* root_dir_fid */
7670                 smb_fname,                              /* fname */
7671                 DELETE_ACCESS,                          /* access_mask */
7672                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
7673                     FILE_SHARE_DELETE),
7674                 FILE_OPEN,                              /* create_disposition*/
7675                 create_options,                         /* create_options */
7676                 FILE_FLAG_POSIX_SEMANTICS|0777,         /* file_attributes */
7677                 0,                                      /* oplock_request */
7678                 0,                                      /* allocation_size */
7679                 0,                                      /* private_flags */
7680                 NULL,                                   /* sd */
7681                 NULL,                                   /* ea_list */
7682                 &fsp,                                   /* result */
7683                 &info);                                 /* pinfo */
7684
7685         if (!NT_STATUS_IS_OK(status)) {
7686                 return status;
7687         }
7688
7689         /*
7690          * Don't lie to client. If we can't really delete due to
7691          * non-POSIX opens return SHARING_VIOLATION.
7692          */
7693
7694         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
7695         if (lck == NULL) {
7696                 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
7697                           "lock for file %s\n", fsp_str_dbg(fsp)));
7698                 close_file(req, fsp, NORMAL_CLOSE);
7699                 return NT_STATUS_INVALID_PARAMETER;
7700         }
7701
7702         /*
7703          * See if others still have the file open. If this is the case, then
7704          * don't delete. If all opens are POSIX delete we can set the delete
7705          * on close disposition.
7706          */
7707         for (i=0; i<lck->data->num_share_modes; i++) {
7708                 struct share_mode_entry *e = &lck->data->share_modes[i];
7709                 if (is_valid_share_mode_entry(e)) {
7710                         if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
7711                                 continue;
7712                         }
7713                         if (share_mode_stale_pid(lck->data, i)) {
7714                                 continue;
7715                         }
7716                         /* Fail with sharing violation. */
7717                         TALLOC_FREE(lck);
7718                         close_file(req, fsp, NORMAL_CLOSE);
7719                         return NT_STATUS_SHARING_VIOLATION;
7720                 }
7721         }
7722
7723         /*
7724          * Set the delete on close.
7725          */
7726         status = smb_set_file_disposition_info(conn,
7727                                                 &del,
7728                                                 1,
7729                                                 fsp,
7730                                                 smb_fname);
7731
7732         TALLOC_FREE(lck);
7733
7734         if (!NT_STATUS_IS_OK(status)) {
7735                 close_file(req, fsp, NORMAL_CLOSE);
7736                 return status;
7737         }
7738         return close_file(req, fsp, NORMAL_CLOSE);
7739 }
7740
7741 NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
7742                                 struct smb_request *req,
7743                                 TALLOC_CTX *mem_ctx,
7744                                 uint16_t info_level,
7745                                 files_struct *fsp,
7746                                 struct smb_filename *smb_fname,
7747                                 char **ppdata, int total_data,
7748                                 int *ret_data_size)
7749 {
7750         char *pdata = *ppdata;
7751         NTSTATUS status = NT_STATUS_OK;
7752         int data_return_size = 0;
7753
7754         *ret_data_size = 0;
7755
7756         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
7757                 return NT_STATUS_INVALID_LEVEL;
7758         }
7759
7760         if (!CAN_WRITE(conn)) {
7761                 /* Allow POSIX opens. The open path will deny
7762                  * any non-readonly opens. */
7763                 if (info_level != SMB_POSIX_PATH_OPEN) {
7764                         return NT_STATUS_DOS(ERRSRV, ERRaccess);
7765                 }
7766         }
7767
7768         DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "
7769                  "totdata=%d\n", smb_fname_str_dbg(smb_fname),
7770                  fsp_fnum_dbg(fsp),
7771                  info_level, total_data));
7772
7773         switch (info_level) {
7774
7775                 case SMB_INFO_STANDARD:
7776                 {
7777                         status = smb_set_info_standard(conn,
7778                                         pdata,
7779                                         total_data,
7780                                         fsp,
7781                                         smb_fname);
7782                         break;
7783                 }
7784
7785                 case SMB_INFO_SET_EA:
7786                 {
7787                         status = smb_info_set_ea(conn,
7788                                                 pdata,
7789                                                 total_data,
7790                                                 fsp,
7791                                                 smb_fname);
7792                         break;
7793                 }
7794
7795                 case SMB_SET_FILE_BASIC_INFO:
7796                 case SMB_FILE_BASIC_INFORMATION:
7797                 {
7798                         status = smb_set_file_basic_info(conn,
7799                                                         pdata,
7800                                                         total_data,
7801                                                         fsp,
7802                                                         smb_fname);
7803                         break;
7804                 }
7805
7806                 case SMB_FILE_ALLOCATION_INFORMATION:
7807                 case SMB_SET_FILE_ALLOCATION_INFO:
7808                 {
7809                         status = smb_set_file_allocation_info(conn, req,
7810                                                                 pdata,
7811                                                                 total_data,
7812                                                                 fsp,
7813                                                                 smb_fname);
7814                         break;
7815                 }
7816
7817                 case SMB_FILE_END_OF_FILE_INFORMATION:
7818                 case SMB_SET_FILE_END_OF_FILE_INFO:
7819                 {
7820                         /*
7821                          * XP/Win7 both fail after the createfile with
7822                          * SMB_SET_FILE_END_OF_FILE_INFO but not
7823                          * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
7824                          * The level is known here, so pass it down
7825                          * appropriately.
7826                          */
7827                         bool should_fail =
7828                             (info_level == SMB_SET_FILE_END_OF_FILE_INFO);
7829
7830                         status = smb_set_file_end_of_file_info(conn, req,
7831                                                                 pdata,
7832                                                                 total_data,
7833                                                                 fsp,
7834                                                                 smb_fname,
7835                                                                 should_fail);
7836                         break;
7837                 }
7838
7839                 case SMB_FILE_DISPOSITION_INFORMATION:
7840                 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
7841                 {
7842 #if 0
7843                         /* JRA - We used to just ignore this on a path ? 
7844                          * Shouldn't this be invalid level on a pathname
7845                          * based call ?
7846                          */
7847                         if (tran_call != TRANSACT2_SETFILEINFO) {
7848                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
7849                         }
7850 #endif
7851                         status = smb_set_file_disposition_info(conn,
7852                                                 pdata,
7853                                                 total_data,
7854                                                 fsp,
7855                                                 smb_fname);
7856                         break;
7857                 }
7858
7859                 case SMB_FILE_POSITION_INFORMATION:
7860                 {
7861                         status = smb_file_position_information(conn,
7862                                                 pdata,
7863                                                 total_data,
7864                                                 fsp);
7865                         break;
7866                 }
7867
7868                 case SMB_FILE_FULL_EA_INFORMATION:
7869                 {
7870                         status = smb_set_file_full_ea_info(conn,
7871                                                 pdata,
7872                                                 total_data,
7873                                                 fsp);
7874                         break;
7875                 }
7876
7877                 /* From tridge Samba4 : 
7878                  * MODE_INFORMATION in setfileinfo (I have no
7879                  * idea what "mode information" on a file is - it takes a value of 0,
7880                  * 2, 4 or 6. What could it be?).
7881                  */
7882
7883                 case SMB_FILE_MODE_INFORMATION:
7884                 {
7885                         status = smb_file_mode_information(conn,
7886                                                 pdata,
7887                                                 total_data);
7888                         break;
7889                 }
7890
7891                 /*
7892                  * CIFS UNIX extensions.
7893                  */
7894
7895                 case SMB_SET_FILE_UNIX_BASIC:
7896                 {
7897                         status = smb_set_file_unix_basic(conn, req,
7898                                                         pdata,
7899                                                         total_data,
7900                                                         fsp,
7901                                                         smb_fname);
7902                         break;
7903                 }
7904
7905                 case SMB_SET_FILE_UNIX_INFO2:
7906                 {
7907                         status = smb_set_file_unix_info2(conn, req,
7908                                                         pdata,
7909                                                         total_data,
7910                                                         fsp,
7911                                                         smb_fname);
7912                         break;
7913                 }
7914
7915                 case SMB_SET_FILE_UNIX_LINK:
7916                 {
7917                         if (fsp) {
7918                                 /* We must have a pathname for this. */
7919                                 return NT_STATUS_INVALID_LEVEL;
7920                         }
7921                         status = smb_set_file_unix_link(conn, req, pdata,
7922                                                         total_data, smb_fname);
7923                         break;
7924                 }
7925
7926                 case SMB_SET_FILE_UNIX_HLINK:
7927                 {
7928                         if (fsp) {
7929                                 /* We must have a pathname for this. */
7930                                 return NT_STATUS_INVALID_LEVEL;
7931                         }
7932                         status = smb_set_file_unix_hlink(conn, req,
7933                                                          pdata, total_data,
7934                                                          smb_fname);
7935                         break;
7936                 }
7937
7938                 case SMB_FILE_RENAME_INFORMATION:
7939                 {
7940                         status = smb_file_rename_information(conn, req,
7941                                                              pdata, total_data,
7942                                                              fsp, smb_fname);
7943                         break;
7944                 }
7945
7946                 case SMB2_FILE_RENAME_INFORMATION_INTERNAL:
7947                 {
7948                         /* SMB2 rename information. */
7949                         status = smb2_file_rename_information(conn, req,
7950                                                              pdata, total_data,
7951                                                              fsp, smb_fname);
7952                         break;
7953                 }
7954
7955                 case SMB_FILE_LINK_INFORMATION:
7956                 {
7957                         status = smb_file_link_information(conn, req,
7958                                                         pdata, total_data,
7959                                                         fsp, smb_fname);
7960                         break;
7961                 }
7962
7963 #if defined(HAVE_POSIX_ACLS)
7964                 case SMB_SET_POSIX_ACL:
7965                 {
7966                         status = smb_set_posix_acl(conn,
7967                                                 pdata,
7968                                                 total_data,
7969                                                 fsp,
7970                                                 smb_fname);
7971                         break;
7972                 }
7973 #endif
7974
7975                 case SMB_SET_POSIX_LOCK:
7976                 {
7977                         if (!fsp) {
7978                                 return NT_STATUS_INVALID_LEVEL;
7979                         }
7980                         status = smb_set_posix_lock(conn, req,
7981                                                     pdata, total_data, fsp);
7982                         break;
7983                 }
7984
7985                 case SMB_POSIX_PATH_OPEN:
7986                 {
7987                         if (fsp) {
7988                                 /* We must have a pathname for this. */
7989                                 return NT_STATUS_INVALID_LEVEL;
7990                         }
7991
7992                         status = smb_posix_open(conn, req,
7993                                                 ppdata,
7994                                                 total_data,
7995                                                 smb_fname,
7996                                                 &data_return_size);
7997                         break;
7998                 }
7999
8000                 case SMB_POSIX_PATH_UNLINK:
8001                 {
8002                         if (fsp) {
8003                                 /* We must have a pathname for this. */
8004                                 return NT_STATUS_INVALID_LEVEL;
8005                         }
8006
8007                         status = smb_posix_unlink(conn, req,
8008                                                 pdata,
8009                                                 total_data,
8010                                                 smb_fname);
8011                         break;
8012                 }
8013
8014                 default:
8015                         return NT_STATUS_INVALID_LEVEL;
8016         }
8017
8018         if (!NT_STATUS_IS_OK(status)) {
8019                 return status;
8020         }
8021
8022         *ret_data_size = data_return_size;
8023         return NT_STATUS_OK;
8024 }
8025
8026 /****************************************************************************
8027  Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
8028 ****************************************************************************/
8029
8030 static void call_trans2setfilepathinfo(connection_struct *conn,
8031                                        struct smb_request *req,
8032                                        unsigned int tran_call,
8033                                        char **pparams, int total_params,
8034                                        char **ppdata, int total_data,
8035                                        unsigned int max_data_bytes)
8036 {
8037         char *params = *pparams;
8038         char *pdata = *ppdata;
8039         uint16 info_level;
8040         struct smb_filename *smb_fname = NULL;
8041         files_struct *fsp = NULL;
8042         NTSTATUS status = NT_STATUS_OK;
8043         int data_return_size = 0;
8044
8045         if (!params) {
8046                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8047                 return;
8048         }
8049
8050         if (tran_call == TRANSACT2_SETFILEINFO) {
8051                 if (total_params < 4) {
8052                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8053                         return;
8054                 }
8055
8056                 fsp = file_fsp(req, SVAL(params,0));
8057                 /* Basic check for non-null fsp. */
8058                 if (!check_fsp_open(conn, req, fsp)) {
8059                         return;
8060                 }
8061                 info_level = SVAL(params,2);
8062
8063                 smb_fname = cp_smb_filename(talloc_tos(), fsp->fsp_name);
8064                 if (smb_fname == NULL) {
8065                         reply_nterror(req, NT_STATUS_NO_MEMORY);
8066                         return;
8067                 }
8068
8069                 if(fsp->fh->fd == -1) {
8070                         /*
8071                          * This is actually a SETFILEINFO on a directory
8072                          * handle (returned from an NT SMB). NT5.0 seems
8073                          * to do this call. JRA.
8074                          */
8075                         if (INFO_LEVEL_IS_UNIX(info_level)) {
8076                                 /* Always do lstat for UNIX calls. */
8077                                 if (SMB_VFS_LSTAT(conn, smb_fname)) {
8078                                         DEBUG(3,("call_trans2setfilepathinfo: "
8079                                                  "SMB_VFS_LSTAT of %s failed "
8080                                                  "(%s)\n",
8081                                                  smb_fname_str_dbg(smb_fname),
8082                                                  strerror(errno)));
8083                                         reply_nterror(req, map_nt_error_from_unix(errno));
8084                                         return;
8085                                 }
8086                         } else {
8087                                 if (SMB_VFS_STAT(conn, smb_fname) != 0) {
8088                                         DEBUG(3,("call_trans2setfilepathinfo: "
8089                                                  "fileinfo of %s failed (%s)\n",
8090                                                  smb_fname_str_dbg(smb_fname),
8091                                                  strerror(errno)));
8092                                         reply_nterror(req, map_nt_error_from_unix(errno));
8093                                         return;
8094                                 }
8095                         }
8096                 } else if (fsp->print_file) {
8097                         /*
8098                          * Doing a DELETE_ON_CLOSE should cancel a print job.
8099                          */
8100                         if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
8101                                 fsp->fh->private_options |= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE;
8102
8103                                 DEBUG(3,("call_trans2setfilepathinfo: "
8104                                          "Cancelling print job (%s)\n",
8105                                          fsp_str_dbg(fsp)));
8106
8107                                 SSVAL(params,0,0);
8108                                 send_trans2_replies(conn, req, params, 2,
8109                                                     *ppdata, 0,
8110                                                     max_data_bytes);
8111                                 return;
8112                         } else {
8113                                 reply_nterror(req,
8114                                         NT_STATUS_OBJECT_PATH_NOT_FOUND);
8115                                 return;
8116                         }
8117                 } else {
8118                         /*
8119                          * Original code - this is an open file.
8120                          */
8121                         if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
8122                                 DEBUG(3,("call_trans2setfilepathinfo: fstat "
8123                                          "of %s failed (%s)\n", fsp_fnum_dbg(fsp),
8124                                          strerror(errno)));
8125                                 reply_nterror(req, map_nt_error_from_unix(errno));
8126                                 return;
8127                         }
8128                 }
8129         } else {
8130                 char *fname = NULL;
8131                 uint32_t ucf_flags = 0;
8132
8133                 /* set path info */
8134                 if (total_params < 7) {
8135                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8136                         return;
8137                 }
8138
8139                 info_level = SVAL(params,0);
8140                 srvstr_get_path(req, params, req->flags2, &fname, &params[6],
8141                                 total_params - 6, STR_TERMINATE,
8142                                 &status);
8143                 if (!NT_STATUS_IS_OK(status)) {
8144                         reply_nterror(req, status);
8145                         return;
8146                 }
8147
8148                 if (info_level == SMB_SET_FILE_UNIX_BASIC ||
8149                                 info_level == SMB_SET_FILE_UNIX_INFO2 ||
8150                                 info_level == SMB_FILE_RENAME_INFORMATION ||
8151                                 info_level == SMB_POSIX_PATH_UNLINK) {
8152                         ucf_flags |= UCF_UNIX_NAME_LOOKUP;
8153                 }
8154
8155                 status = filename_convert(req, conn,
8156                                          req->flags2 & FLAGS2_DFS_PATHNAMES,
8157                                          fname,
8158                                          ucf_flags,
8159                                          NULL,
8160                                          &smb_fname);
8161                 if (!NT_STATUS_IS_OK(status)) {
8162                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
8163                                 reply_botherror(req,
8164                                                 NT_STATUS_PATH_NOT_COVERED,
8165                                                 ERRSRV, ERRbadpath);
8166                                 return;
8167                         }
8168                         reply_nterror(req, status);
8169                         return;
8170                 }
8171
8172                 if (INFO_LEVEL_IS_UNIX(info_level)) {
8173                         /*
8174                          * For CIFS UNIX extensions the target name may not exist.
8175                          */
8176
8177                         /* Always do lstat for UNIX calls. */
8178                         SMB_VFS_LSTAT(conn, smb_fname);
8179
8180                 } else if (!VALID_STAT(smb_fname->st) &&
8181                            SMB_VFS_STAT(conn, smb_fname)) {
8182                         DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
8183                                  "%s failed (%s)\n",
8184                                  smb_fname_str_dbg(smb_fname),
8185                                  strerror(errno)));
8186                         reply_nterror(req, map_nt_error_from_unix(errno));
8187                         return;
8188                 }
8189         }
8190
8191         DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
8192                  "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
8193                  fsp_fnum_dbg(fsp),
8194                  info_level,total_data));
8195
8196         /* Realloc the parameter size */
8197         *pparams = (char *)SMB_REALLOC(*pparams,2);
8198         if (*pparams == NULL) {
8199                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8200                 return;
8201         }
8202         params = *pparams;
8203
8204         SSVAL(params,0,0);
8205
8206         status = smbd_do_setfilepathinfo(conn, req, req,
8207                                          info_level,
8208                                          fsp,
8209                                          smb_fname,
8210                                          ppdata, total_data,
8211                                          &data_return_size);
8212         if (!NT_STATUS_IS_OK(status)) {
8213                 if (open_was_deferred(req->sconn, req->mid)) {
8214                         /* We have re-scheduled this call. */
8215                         return;
8216                 }
8217                 if (blocking_lock_was_deferred_smb1(req->sconn, req->mid)) {
8218                         /* We have re-scheduled this call. */
8219                         return;
8220                 }
8221                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
8222                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
8223                                         ERRSRV, ERRbadpath);
8224                         return;
8225                 }
8226                 if (info_level == SMB_POSIX_PATH_OPEN) {
8227                         reply_openerror(req, status);
8228                         return;
8229                 }
8230
8231                 reply_nterror(req, status);
8232                 return;
8233         }
8234
8235         send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
8236                             max_data_bytes);
8237
8238         return;
8239 }
8240
8241 /****************************************************************************
8242  Reply to a TRANS2_MKDIR (make directory with extended attributes).
8243 ****************************************************************************/
8244
8245 static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
8246                              char **pparams, int total_params,
8247                              char **ppdata, int total_data,
8248                              unsigned int max_data_bytes)
8249 {
8250         struct smb_filename *smb_dname = NULL;
8251         char *params = *pparams;
8252         char *pdata = *ppdata;
8253         char *directory = NULL;
8254         NTSTATUS status = NT_STATUS_OK;
8255         struct ea_list *ea_list = NULL;
8256         TALLOC_CTX *ctx = talloc_tos();
8257
8258         if (!CAN_WRITE(conn)) {
8259                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
8260                 return;
8261         }
8262
8263         if (total_params < 5) {
8264                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8265                 return;
8266         }
8267
8268         srvstr_get_path(ctx, params, req->flags2, &directory, &params[4],
8269                         total_params - 4, STR_TERMINATE,
8270                         &status);
8271         if (!NT_STATUS_IS_OK(status)) {
8272                 reply_nterror(req, status);
8273                 return;
8274         }
8275
8276         DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
8277
8278         status = filename_convert(ctx,
8279                                 conn,
8280                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
8281                                 directory,
8282                                 0,
8283                                 NULL,
8284                                 &smb_dname);
8285
8286         if (!NT_STATUS_IS_OK(status)) {
8287                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
8288                         reply_botherror(req,
8289                                 NT_STATUS_PATH_NOT_COVERED,
8290                                 ERRSRV, ERRbadpath);
8291                         return;
8292                 }
8293                 reply_nterror(req, status);
8294                 return;
8295         }
8296
8297         /*
8298          * OS/2 workplace shell seems to send SET_EA requests of "null"
8299          * length (4 bytes containing IVAL 4).
8300          * They seem to have no effect. Bug #3212. JRA.
8301          */
8302
8303         if (total_data && (total_data != 4)) {
8304                 /* Any data in this call is an EA list. */
8305                 if (total_data < 10) {
8306                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8307                         goto out;
8308                 }
8309
8310                 if (IVAL(pdata,0) > total_data) {
8311                         DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
8312                                 IVAL(pdata,0), (unsigned int)total_data));
8313                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8314                         goto out;
8315                 }
8316
8317                 ea_list = read_ea_list(talloc_tos(), pdata + 4,
8318                                        total_data - 4);
8319                 if (!ea_list) {
8320                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8321                         goto out;
8322                 }
8323
8324                 if (!lp_ea_support(SNUM(conn))) {
8325                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
8326                         goto out;
8327                 }
8328         }
8329         /* If total_data == 4 Windows doesn't care what values
8330          * are placed in that field, it just ignores them.
8331          * The System i QNTC IBM SMB client puts bad values here,
8332          * so ignore them. */
8333
8334         status = create_directory(conn, req, smb_dname);
8335
8336         if (!NT_STATUS_IS_OK(status)) {
8337                 reply_nterror(req, status);
8338                 goto out;
8339         }
8340
8341         /* Try and set any given EA. */
8342         if (ea_list) {
8343                 status = set_ea(conn, NULL, smb_dname, ea_list);
8344                 if (!NT_STATUS_IS_OK(status)) {
8345                         reply_nterror(req, status);
8346                         goto out;
8347                 }
8348         }
8349
8350         /* Realloc the parameter and data sizes */
8351         *pparams = (char *)SMB_REALLOC(*pparams,2);
8352         if(*pparams == NULL) {
8353                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8354                 goto out;
8355         }
8356         params = *pparams;
8357
8358         SSVAL(params,0,0);
8359
8360         send_trans2_replies(conn, req, params, 2, *ppdata, 0, max_data_bytes);
8361
8362  out:
8363         TALLOC_FREE(smb_dname);
8364         return;
8365 }
8366
8367 /****************************************************************************
8368  Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
8369  We don't actually do this - we just send a null response.
8370 ****************************************************************************/
8371
8372 static void call_trans2findnotifyfirst(connection_struct *conn,
8373                                        struct smb_request *req,
8374                                        char **pparams, int total_params,
8375                                        char **ppdata, int total_data,
8376                                        unsigned int max_data_bytes)
8377 {
8378         char *params = *pparams;
8379         uint16 info_level;
8380
8381         if (total_params < 6) {
8382                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8383                 return;
8384         }
8385
8386         info_level = SVAL(params,4);
8387         DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
8388
8389         switch (info_level) {
8390                 case 1:
8391                 case 2:
8392                         break;
8393                 default:
8394                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
8395                         return;
8396         }
8397
8398         /* Realloc the parameter and data sizes */
8399         *pparams = (char *)SMB_REALLOC(*pparams,6);
8400         if (*pparams == NULL) {
8401                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8402                 return;
8403         }
8404         params = *pparams;
8405
8406         SSVAL(params,0,fnf_handle);
8407         SSVAL(params,2,0); /* No changes */
8408         SSVAL(params,4,0); /* No EA errors */
8409
8410         fnf_handle++;
8411
8412         if(fnf_handle == 0)
8413                 fnf_handle = 257;
8414
8415         send_trans2_replies(conn, req, params, 6, *ppdata, 0, max_data_bytes);
8416
8417         return;
8418 }
8419
8420 /****************************************************************************
8421  Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for 
8422  changes). Currently this does nothing.
8423 ****************************************************************************/
8424
8425 static void call_trans2findnotifynext(connection_struct *conn,
8426                                       struct smb_request *req,
8427                                       char **pparams, int total_params,
8428                                       char **ppdata, int total_data,
8429                                       unsigned int max_data_bytes)
8430 {
8431         char *params = *pparams;
8432
8433         DEBUG(3,("call_trans2findnotifynext\n"));
8434
8435         /* Realloc the parameter and data sizes */
8436         *pparams = (char *)SMB_REALLOC(*pparams,4);
8437         if (*pparams == NULL) {
8438                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8439                 return;
8440         }
8441         params = *pparams;
8442
8443         SSVAL(params,0,0); /* No changes */
8444         SSVAL(params,2,0); /* No EA errors */
8445
8446         send_trans2_replies(conn, req, params, 4, *ppdata, 0, max_data_bytes);
8447
8448         return;
8449 }
8450
8451 /****************************************************************************
8452  Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
8453 ****************************************************************************/
8454
8455 static void call_trans2getdfsreferral(connection_struct *conn,
8456                                       struct smb_request *req,
8457                                       char **pparams, int total_params,
8458                                       char **ppdata, int total_data,
8459                                       unsigned int max_data_bytes)
8460 {
8461         char *params = *pparams;
8462         char *pathname = NULL;
8463         int reply_size = 0;
8464         int max_referral_level;
8465         NTSTATUS status = NT_STATUS_OK;
8466         TALLOC_CTX *ctx = talloc_tos();
8467
8468         DEBUG(10,("call_trans2getdfsreferral\n"));
8469
8470         if (total_params < 3) {
8471                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8472                 return;
8473         }
8474
8475         max_referral_level = SVAL(params,0);
8476
8477         if(!lp_host_msdfs()) {
8478                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
8479                 return;
8480         }
8481
8482         srvstr_pull_talloc(ctx, params, req->flags2, &pathname, &params[2],
8483                     total_params - 2, STR_TERMINATE);
8484         if (!pathname) {
8485                 reply_nterror(req, NT_STATUS_NOT_FOUND);
8486                 return;
8487         }
8488         if((reply_size = setup_dfs_referral(conn, pathname, max_referral_level,
8489                                             ppdata,&status)) < 0) {
8490                 reply_nterror(req, status);
8491                 return;
8492         }
8493
8494         SSVAL((discard_const_p(uint8_t, req->inbuf)), smb_flg2,
8495               SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
8496         send_trans2_replies(conn, req,0,0,*ppdata,reply_size, max_data_bytes);
8497
8498         return;
8499 }
8500
8501 #define LMCAT_SPL       0x53
8502 #define LMFUNC_GETJOBID 0x60
8503
8504 /****************************************************************************
8505  Reply to a TRANS2_IOCTL - used for OS/2 printing.
8506 ****************************************************************************/
8507
8508 static void call_trans2ioctl(connection_struct *conn,
8509                              struct smb_request *req,
8510                              char **pparams, int total_params,
8511                              char **ppdata, int total_data,
8512                              unsigned int max_data_bytes)
8513 {
8514         char *pdata = *ppdata;
8515         files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0));
8516
8517         /* check for an invalid fid before proceeding */
8518
8519         if (!fsp) {
8520                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
8521                 return;
8522         }
8523
8524         if ((SVAL(req->vwv+16, 0) == LMCAT_SPL)
8525             && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
8526                 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
8527                 if (*ppdata == NULL) {
8528                         reply_nterror(req, NT_STATUS_NO_MEMORY);
8529                         return;
8530                 }
8531                 pdata = *ppdata;
8532
8533                 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
8534                         CAN ACCEPT THIS IN UNICODE. JRA. */
8535
8536                 /* Job number */
8537                 SSVAL(pdata, 0, print_spool_rap_jobid(fsp->print_file));
8538
8539                 srvstr_push(pdata, req->flags2, pdata + 2,
8540                             lp_netbios_name(), 15,
8541                             STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
8542                 srvstr_push(pdata, req->flags2, pdata+18,
8543                             lp_servicename(talloc_tos(), SNUM(conn)), 13,
8544                             STR_ASCII|STR_TERMINATE); /* Service name */
8545                 send_trans2_replies(conn, req, *pparams, 0, *ppdata, 32,
8546                                     max_data_bytes);
8547                 return;
8548         }
8549
8550         DEBUG(2,("Unknown TRANS2_IOCTL\n"));
8551         reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
8552 }
8553
8554 /****************************************************************************
8555  Reply to a SMBfindclose (stop trans2 directory search).
8556 ****************************************************************************/
8557
8558 void reply_findclose(struct smb_request *req)
8559 {
8560         int dptr_num;
8561         struct smbd_server_connection *sconn = req->sconn;
8562
8563         START_PROFILE(SMBfindclose);
8564
8565         if (req->wct < 1) {
8566                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8567                 END_PROFILE(SMBfindclose);
8568                 return;
8569         }
8570
8571         dptr_num = SVALS(req->vwv+0, 0);
8572
8573         DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
8574
8575         dptr_close(sconn, &dptr_num);
8576
8577         reply_outbuf(req, 0, 0);
8578
8579         DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
8580
8581         END_PROFILE(SMBfindclose);
8582         return;
8583 }
8584
8585 /****************************************************************************
8586  Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
8587 ****************************************************************************/
8588
8589 void reply_findnclose(struct smb_request *req)
8590 {
8591         int dptr_num;
8592
8593         START_PROFILE(SMBfindnclose);
8594
8595         if (req->wct < 1) {
8596                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8597                 END_PROFILE(SMBfindnclose);
8598                 return;
8599         }
8600
8601         dptr_num = SVAL(req->vwv+0, 0);
8602
8603         DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
8604
8605         /* We never give out valid handles for a 
8606            findnotifyfirst - so any dptr_num is ok here. 
8607            Just ignore it. */
8608
8609         reply_outbuf(req, 0, 0);
8610
8611         DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
8612
8613         END_PROFILE(SMBfindnclose);
8614         return;
8615 }
8616
8617 static void handle_trans2(connection_struct *conn, struct smb_request *req,
8618                           struct trans_state *state)
8619 {
8620         if (get_Protocol() >= PROTOCOL_NT1) {
8621                 req->flags2 |= 0x40; /* IS_LONG_NAME */
8622                 SSVAL((discard_const_p(uint8_t, req->inbuf)),smb_flg2,req->flags2);
8623         }
8624
8625         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
8626                 if (state->call != TRANSACT2_QFSINFO &&
8627                     state->call != TRANSACT2_SETFSINFO) {
8628                         DEBUG(0,("handle_trans2: encryption required "
8629                                 "with call 0x%x\n",
8630                                 (unsigned int)state->call));
8631                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
8632                         return;
8633                 }
8634         }
8635
8636         SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
8637
8638         /* Now we must call the relevant TRANS2 function */
8639         switch(state->call)  {
8640         case TRANSACT2_OPEN:
8641         {
8642                 START_PROFILE(Trans2_open);
8643                 call_trans2open(conn, req,
8644                                 &state->param, state->total_param,
8645                                 &state->data, state->total_data,
8646                                 state->max_data_return);
8647                 END_PROFILE(Trans2_open);
8648                 break;
8649         }
8650
8651         case TRANSACT2_FINDFIRST:
8652         {
8653                 START_PROFILE(Trans2_findfirst);
8654                 call_trans2findfirst(conn, req,
8655                                      &state->param, state->total_param,
8656                                      &state->data, state->total_data,
8657                                      state->max_data_return);
8658                 END_PROFILE(Trans2_findfirst);
8659                 break;
8660         }
8661
8662         case TRANSACT2_FINDNEXT:
8663         {
8664                 START_PROFILE(Trans2_findnext);
8665                 call_trans2findnext(conn, req,
8666                                     &state->param, state->total_param,
8667                                     &state->data, state->total_data,
8668                                     state->max_data_return);
8669                 END_PROFILE(Trans2_findnext);
8670                 break;
8671         }
8672
8673         case TRANSACT2_QFSINFO:
8674         {
8675                 START_PROFILE(Trans2_qfsinfo);
8676                 call_trans2qfsinfo(conn, req,
8677                                    &state->param, state->total_param,
8678                                    &state->data, state->total_data,
8679                                    state->max_data_return);
8680                 END_PROFILE(Trans2_qfsinfo);
8681             break;
8682         }
8683
8684         case TRANSACT2_SETFSINFO:
8685         {
8686                 START_PROFILE(Trans2_setfsinfo);
8687                 call_trans2setfsinfo(conn, req,
8688                                      &state->param, state->total_param,
8689                                      &state->data, state->total_data,
8690                                      state->max_data_return);
8691                 END_PROFILE(Trans2_setfsinfo);
8692                 break;
8693         }
8694
8695         case TRANSACT2_QPATHINFO:
8696         case TRANSACT2_QFILEINFO:
8697         {
8698                 START_PROFILE(Trans2_qpathinfo);
8699                 call_trans2qfilepathinfo(conn, req, state->call,
8700                                          &state->param, state->total_param,
8701                                          &state->data, state->total_data,
8702                                          state->max_data_return);
8703                 END_PROFILE(Trans2_qpathinfo);
8704                 break;
8705         }
8706
8707         case TRANSACT2_SETPATHINFO:
8708         case TRANSACT2_SETFILEINFO:
8709         {
8710                 START_PROFILE(Trans2_setpathinfo);
8711                 call_trans2setfilepathinfo(conn, req, state->call,
8712                                            &state->param, state->total_param,
8713                                            &state->data, state->total_data,
8714                                            state->max_data_return);
8715                 END_PROFILE(Trans2_setpathinfo);
8716                 break;
8717         }
8718
8719         case TRANSACT2_FINDNOTIFYFIRST:
8720         {
8721                 START_PROFILE(Trans2_findnotifyfirst);
8722                 call_trans2findnotifyfirst(conn, req,
8723                                            &state->param, state->total_param,
8724                                            &state->data, state->total_data,
8725                                            state->max_data_return);
8726                 END_PROFILE(Trans2_findnotifyfirst);
8727                 break;
8728         }
8729
8730         case TRANSACT2_FINDNOTIFYNEXT:
8731         {
8732                 START_PROFILE(Trans2_findnotifynext);
8733                 call_trans2findnotifynext(conn, req,
8734                                           &state->param, state->total_param,
8735                                           &state->data, state->total_data,
8736                                           state->max_data_return);
8737                 END_PROFILE(Trans2_findnotifynext);
8738                 break;
8739         }
8740
8741         case TRANSACT2_MKDIR:
8742         {
8743                 START_PROFILE(Trans2_mkdir);
8744                 call_trans2mkdir(conn, req,
8745                                  &state->param, state->total_param,
8746                                  &state->data, state->total_data,
8747                                  state->max_data_return);
8748                 END_PROFILE(Trans2_mkdir);
8749                 break;
8750         }
8751
8752         case TRANSACT2_GET_DFS_REFERRAL:
8753         {
8754                 START_PROFILE(Trans2_get_dfs_referral);
8755                 call_trans2getdfsreferral(conn, req,
8756                                           &state->param, state->total_param,
8757                                           &state->data, state->total_data,
8758                                           state->max_data_return);
8759                 END_PROFILE(Trans2_get_dfs_referral);
8760                 break;
8761         }
8762
8763         case TRANSACT2_IOCTL:
8764         {
8765                 START_PROFILE(Trans2_ioctl);
8766                 call_trans2ioctl(conn, req,
8767                                  &state->param, state->total_param,
8768                                  &state->data, state->total_data,
8769                                  state->max_data_return);
8770                 END_PROFILE(Trans2_ioctl);
8771                 break;
8772         }
8773
8774         default:
8775                 /* Error in request */
8776                 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
8777                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
8778         }
8779 }
8780
8781 /****************************************************************************
8782  Reply to a SMBtrans2.
8783  ****************************************************************************/
8784
8785 void reply_trans2(struct smb_request *req)
8786 {
8787         connection_struct *conn = req->conn;
8788         unsigned int dsoff;
8789         unsigned int dscnt;
8790         unsigned int psoff;
8791         unsigned int pscnt;
8792         unsigned int tran_call;
8793         struct trans_state *state;
8794         NTSTATUS result;
8795
8796         START_PROFILE(SMBtrans2);
8797
8798         if (req->wct < 14) {
8799                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8800                 END_PROFILE(SMBtrans2);
8801                 return;
8802         }
8803
8804         dsoff = SVAL(req->vwv+12, 0);
8805         dscnt = SVAL(req->vwv+11, 0);
8806         psoff = SVAL(req->vwv+10, 0);
8807         pscnt = SVAL(req->vwv+9, 0);
8808         tran_call = SVAL(req->vwv+14, 0);
8809
8810         result = allow_new_trans(conn->pending_trans, req->mid);
8811         if (!NT_STATUS_IS_OK(result)) {
8812                 DEBUG(2, ("Got invalid trans2 request: %s\n",
8813                           nt_errstr(result)));
8814                 reply_nterror(req, result);
8815                 END_PROFILE(SMBtrans2);
8816                 return;
8817         }
8818
8819         if (IS_IPC(conn)) {
8820                 switch (tran_call) {
8821                 /* List the allowed trans2 calls on IPC$ */
8822                 case TRANSACT2_OPEN:
8823                 case TRANSACT2_GET_DFS_REFERRAL:
8824                 case TRANSACT2_QFILEINFO:
8825                 case TRANSACT2_QFSINFO:
8826                 case TRANSACT2_SETFSINFO:
8827                         break;
8828                 default:
8829                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
8830                         END_PROFILE(SMBtrans2);
8831                         return;
8832                 }
8833         }
8834
8835         if ((state = talloc(conn, struct trans_state)) == NULL) {
8836                 DEBUG(0, ("talloc failed\n"));
8837                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8838                 END_PROFILE(SMBtrans2);
8839                 return;
8840         }
8841
8842         state->cmd = SMBtrans2;
8843
8844         state->mid = req->mid;
8845         state->vuid = req->vuid;
8846         state->setup_count = SVAL(req->vwv+13, 0);
8847         state->setup = NULL;
8848         state->total_param = SVAL(req->vwv+0, 0);
8849         state->param = NULL;
8850         state->total_data =  SVAL(req->vwv+1, 0);
8851         state->data = NULL;
8852         state->max_param_return = SVAL(req->vwv+2, 0);
8853         state->max_data_return  = SVAL(req->vwv+3, 0);
8854         state->max_setup_return = SVAL(req->vwv+4, 0);
8855         state->close_on_completion = BITSETW(req->vwv+5, 0);
8856         state->one_way = BITSETW(req->vwv+5, 1);
8857
8858         state->call = tran_call;
8859
8860         /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
8861            is so as a sanity check */
8862         if (state->setup_count != 1) {
8863                 /*
8864                  * Need to have rc=0 for ioctl to get job id for OS/2.
8865                  *  Network printing will fail if function is not successful.
8866                  *  Similar function in reply.c will be used if protocol
8867                  *  is LANMAN1.0 instead of LM1.2X002.
8868                  *  Until DosPrintSetJobInfo with PRJINFO3 is supported,
8869                  *  outbuf doesn't have to be set(only job id is used).
8870                  */
8871                 if ( (state->setup_count == 4)
8872                      && (tran_call == TRANSACT2_IOCTL)
8873                      && (SVAL(req->vwv+16, 0) == LMCAT_SPL)
8874                      && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
8875                         DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
8876                 } else {
8877                         DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
8878                         DEBUG(2,("Transaction is %d\n",tran_call));
8879                         TALLOC_FREE(state);
8880                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8881                         END_PROFILE(SMBtrans2);
8882                         return;
8883                 }
8884         }
8885
8886         if ((dscnt > state->total_data) || (pscnt > state->total_param))
8887                 goto bad_param;
8888
8889         if (state->total_data) {
8890
8891                 if (trans_oob(state->total_data, 0, dscnt)
8892                     || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
8893                         goto bad_param;
8894                 }
8895
8896                 /* Can't use talloc here, the core routines do realloc on the
8897                  * params and data. */
8898                 state->data = (char *)SMB_MALLOC(state->total_data);
8899                 if (state->data == NULL) {
8900                         DEBUG(0,("reply_trans2: data malloc fail for %u "
8901                                  "bytes !\n", (unsigned int)state->total_data));
8902                         TALLOC_FREE(state);
8903                         reply_nterror(req, NT_STATUS_NO_MEMORY);
8904                         END_PROFILE(SMBtrans2);
8905                         return;
8906                 }
8907
8908                 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
8909         }
8910
8911         if (state->total_param) {
8912
8913                 if (trans_oob(state->total_param, 0, pscnt)
8914                     || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
8915                         goto bad_param;
8916                 }
8917
8918                 /* Can't use talloc here, the core routines do realloc on the
8919                  * params and data. */
8920                 state->param = (char *)SMB_MALLOC(state->total_param);
8921                 if (state->param == NULL) {
8922                         DEBUG(0,("reply_trans: param malloc fail for %u "
8923                                  "bytes !\n", (unsigned int)state->total_param));
8924                         SAFE_FREE(state->data);
8925                         TALLOC_FREE(state);
8926                         reply_nterror(req, NT_STATUS_NO_MEMORY);
8927                         END_PROFILE(SMBtrans2);
8928                         return;
8929                 } 
8930
8931                 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
8932         }
8933
8934         state->received_data  = dscnt;
8935         state->received_param = pscnt;
8936
8937         if ((state->received_param == state->total_param) &&
8938             (state->received_data == state->total_data)) {
8939
8940                 handle_trans2(conn, req, state);
8941
8942                 SAFE_FREE(state->data);
8943                 SAFE_FREE(state->param);
8944                 TALLOC_FREE(state);
8945                 END_PROFILE(SMBtrans2);
8946                 return;
8947         }
8948
8949         DLIST_ADD(conn->pending_trans, state);
8950
8951         /* We need to send an interim response then receive the rest
8952            of the parameter/data bytes */
8953         reply_outbuf(req, 0, 0);
8954         show_msg((char *)req->outbuf);
8955         END_PROFILE(SMBtrans2);
8956         return;
8957
8958   bad_param:
8959
8960         DEBUG(0,("reply_trans2: invalid trans parameters\n"));
8961         SAFE_FREE(state->data);
8962         SAFE_FREE(state->param);
8963         TALLOC_FREE(state);
8964         END_PROFILE(SMBtrans2);
8965         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8966 }
8967
8968
8969 /****************************************************************************
8970  Reply to a SMBtranss2
8971  ****************************************************************************/
8972
8973 void reply_transs2(struct smb_request *req)
8974 {
8975         connection_struct *conn = req->conn;
8976         unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
8977         struct trans_state *state;
8978
8979         START_PROFILE(SMBtranss2);
8980
8981         show_msg((const char *)req->inbuf);
8982
8983         /* Windows clients expect all replies to
8984            a transact secondary (SMBtranss2 0x33)
8985            to have a command code of transact
8986            (SMBtrans2 0x32). See bug #8989
8987            and also [MS-CIFS] section 2.2.4.47.2
8988            for details.
8989         */
8990         req->cmd = SMBtrans2;
8991
8992         if (req->wct < 8) {
8993                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8994                 END_PROFILE(SMBtranss2);
8995                 return;
8996         }
8997
8998         for (state = conn->pending_trans; state != NULL;
8999              state = state->next) {
9000                 if (state->mid == req->mid) {
9001                         break;
9002                 }
9003         }
9004
9005         if ((state == NULL) || (state->cmd != SMBtrans2)) {
9006                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9007                 END_PROFILE(SMBtranss2);
9008                 return;
9009         }
9010
9011         /* Revise state->total_param and state->total_data in case they have
9012            changed downwards */
9013
9014         if (SVAL(req->vwv+0, 0) < state->total_param)
9015                 state->total_param = SVAL(req->vwv+0, 0);
9016         if (SVAL(req->vwv+1, 0) < state->total_data)
9017                 state->total_data = SVAL(req->vwv+1, 0);
9018
9019         pcnt = SVAL(req->vwv+2, 0);
9020         poff = SVAL(req->vwv+3, 0);
9021         pdisp = SVAL(req->vwv+4, 0);
9022
9023         dcnt = SVAL(req->vwv+5, 0);
9024         doff = SVAL(req->vwv+6, 0);
9025         ddisp = SVAL(req->vwv+7, 0);
9026
9027         state->received_param += pcnt;
9028         state->received_data += dcnt;
9029
9030         if ((state->received_data > state->total_data) ||
9031             (state->received_param > state->total_param))
9032                 goto bad_param;
9033
9034         if (pcnt) {
9035                 if (trans_oob(state->total_param, pdisp, pcnt)
9036                     || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
9037                         goto bad_param;
9038                 }
9039                 memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
9040         }
9041
9042         if (dcnt) {
9043                 if (trans_oob(state->total_data, ddisp, dcnt)
9044                     || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
9045                         goto bad_param;
9046                 }
9047                 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
9048         }
9049
9050         if ((state->received_param < state->total_param) ||
9051             (state->received_data < state->total_data)) {
9052                 END_PROFILE(SMBtranss2);
9053                 return;
9054         }
9055
9056         handle_trans2(conn, req, state);
9057
9058         DLIST_REMOVE(conn->pending_trans, state);
9059         SAFE_FREE(state->data);
9060         SAFE_FREE(state->param);
9061         TALLOC_FREE(state);
9062
9063         END_PROFILE(SMBtranss2);
9064         return;
9065
9066   bad_param:
9067
9068         DEBUG(0,("reply_transs2: invalid trans parameters\n"));
9069         DLIST_REMOVE(conn->pending_trans, state);
9070         SAFE_FREE(state->data);
9071         SAFE_FREE(state->param);
9072         TALLOC_FREE(state);
9073         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9074         END_PROFILE(SMBtranss2);
9075         return;
9076 }