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