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