3787fa972173f087ceb9953c1946a8c399b65c52
[samba.git] / source3 / smbd / trans2.c
1 /*
2    Unix SMB/CIFS implementation.
3    SMB transaction2 handling
4    Copyright (C) Jeremy Allison                 1994-2007
5    Copyright (C) Stefan (metze) Metzmacher      2003
6    Copyright (C) Volker Lendecke                2005-2007
7    Copyright (C) Steve French                   2005
8    Copyright (C) James Peach                    2006-2007
9
10    Extensively modified by Andrew Tridgell, 1995
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 3 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include "includes.h"
27 #include "system/filesys.h"
28 #include "version.h"
29 #include "smbd/smbd.h"
30 #include "smbd/globals.h"
31 #include "../libcli/auth/libcli_auth.h"
32 #include "../librpc/gen_ndr/xattr.h"
33 #include "../librpc/gen_ndr/ndr_security.h"
34 #include "../librpc/gen_ndr/open_files.h"
35 #include "libcli/security/security.h"
36 #include "trans2.h"
37 #include "auth.h"
38 #include "smbprofile.h"
39 #include "rpc_server/srv_pipe_hnd.h"
40 #include "printing.h"
41
42 #define DIR_ENTRY_SAFETY_MARGIN 4096
43
44 static char *store_file_unix_basic(connection_struct *conn,
45                                 char *pdata,
46                                 files_struct *fsp,
47                                 const SMB_STRUCT_STAT *psbuf);
48
49 static char *store_file_unix_basic_info2(connection_struct *conn,
50                                 char *pdata,
51                                 files_struct *fsp,
52                                 const SMB_STRUCT_STAT *psbuf);
53
54 /********************************************************************
55  The canonical "check access" based on object handle or path function.
56 ********************************************************************/
57
58 NTSTATUS check_access(connection_struct *conn,
59                                 files_struct *fsp,
60                                 const struct smb_filename *smb_fname,
61                                 uint32_t access_mask)
62 {
63         if (fsp) {
64                 if (!(fsp->access_mask & access_mask)) {
65                         return NT_STATUS_ACCESS_DENIED;
66                 }
67         } else {
68                 NTSTATUS status = smbd_check_access_rights(conn,
69                                         smb_fname,
70                                         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 = -1;
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), fsp ? fsp->fnum : -1,
4294                  info_level, max_data_bytes));
4295
4296         mode = dos_mode(conn, smb_fname);
4297         nlink = psbuf->st_ex_nlink;
4298
4299         if (nlink && (mode&FILE_ATTRIBUTE_DIRECTORY)) {
4300                 nlink = 1;
4301         }
4302
4303         if ((nlink > 0) && delete_pending) {
4304                 nlink -= 1;
4305         }
4306
4307         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
4308         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 
4309         if (*ppdata == NULL) {
4310                 return NT_STATUS_NO_MEMORY;
4311         }
4312         pdata = *ppdata;
4313         dstart = pdata;
4314         dend = dstart + data_size - 1;
4315
4316         if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
4317                 update_stat_ex_mtime(psbuf, write_time_ts);
4318         }
4319
4320         create_time_ts = get_create_timespec(conn, fsp, smb_fname);
4321         mtime_ts = psbuf->st_ex_mtime;
4322         atime_ts = psbuf->st_ex_atime;
4323         ctime_ts = get_change_timespec(conn, fsp, smb_fname);
4324
4325         if (lp_dos_filetime_resolution(SNUM(conn))) {
4326                 dos_filetime_timespec(&create_time_ts);
4327                 dos_filetime_timespec(&mtime_ts);
4328                 dos_filetime_timespec(&atime_ts);
4329                 dos_filetime_timespec(&ctime_ts);
4330         }
4331
4332         create_time = convert_timespec_to_time_t(create_time_ts);
4333         mtime = convert_timespec_to_time_t(mtime_ts);
4334         atime = convert_timespec_to_time_t(atime_ts);
4335         c_time = convert_timespec_to_time_t(ctime_ts);
4336
4337         p = strrchr_m(smb_fname->base_name,'/');
4338         if (!p)
4339                 base_name = smb_fname->base_name;
4340         else
4341                 base_name = p+1;
4342
4343         /* NT expects the name to be in an exact form of the *full*
4344            filename. See the trans2 torture test */
4345         if (ISDOT(base_name)) {
4346                 dos_fname = talloc_strdup(mem_ctx, "\\");
4347                 if (!dos_fname) {
4348                         return NT_STATUS_NO_MEMORY;
4349                 }
4350         } else {
4351                 dos_fname = talloc_asprintf(mem_ctx,
4352                                 "\\%s",
4353                                 smb_fname->base_name);
4354                 if (!dos_fname) {
4355                         return NT_STATUS_NO_MEMORY;
4356                 }
4357                 if (is_ntfs_stream_smb_fname(smb_fname)) {
4358                         dos_fname = talloc_asprintf(dos_fname, "%s",
4359                                                     smb_fname->stream_name);
4360                         if (!dos_fname) {
4361                                 return NT_STATUS_NO_MEMORY;
4362                         }
4363                 }
4364
4365                 string_replace(dos_fname, '/', '\\');
4366         }
4367
4368         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, psbuf);
4369
4370         if (!fsp) {
4371                 /* Do we have this path open ? */
4372                 files_struct *fsp1;
4373                 struct file_id fileid = vfs_file_id_from_sbuf(conn, psbuf);
4374                 fsp1 = file_find_di_first(conn->sconn, fileid);
4375                 if (fsp1 && fsp1->initial_allocation_size) {
4376                         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, psbuf);
4377                 }
4378         }
4379
4380         if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
4381                 file_size = get_file_size_stat(psbuf);
4382         }
4383
4384         if (fsp) {
4385                 pos = fsp->fh->position_information;
4386         }
4387
4388         if (fsp) {
4389                 access_mask = fsp->access_mask;
4390         } else {
4391                 /* GENERIC_EXECUTE mapping from Windows */
4392                 access_mask = 0x12019F;
4393         }
4394
4395         /* This should be an index number - looks like
4396            dev/ino to me :-)
4397
4398            I think this causes us to fail the IFSKIT
4399            BasicFileInformationTest. -tpot */
4400         file_index = get_FileIndex(conn, psbuf);
4401
4402         switch (info_level) {
4403                 case SMB_INFO_STANDARD:
4404                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
4405                         data_size = 22;
4406                         srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
4407                         srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
4408                         srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
4409                         SIVAL(pdata,l1_cbFile,(uint32)file_size);
4410                         SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
4411                         SSVAL(pdata,l1_attrFile,mode);
4412                         break;
4413
4414                 case SMB_INFO_QUERY_EA_SIZE:
4415                 {
4416                         unsigned int ea_size =
4417                             estimate_ea_size(conn, fsp,
4418                                              smb_fname->base_name);
4419                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
4420                         data_size = 26;
4421                         srv_put_dos_date2(pdata,0,create_time);
4422                         srv_put_dos_date2(pdata,4,atime);
4423                         srv_put_dos_date2(pdata,8,mtime); /* write time */
4424                         SIVAL(pdata,12,(uint32)file_size);
4425                         SIVAL(pdata,16,(uint32)allocation_size);
4426                         SSVAL(pdata,20,mode);
4427                         SIVAL(pdata,22,ea_size);
4428                         break;
4429                 }
4430
4431                 case SMB_INFO_IS_NAME_VALID:
4432                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
4433                         if (fsp) {
4434                                 /* os/2 needs this ? really ?*/
4435                                 return NT_STATUS_DOS(ERRDOS, ERRbadfunc);
4436                         }
4437                         /* This is only reached for qpathinfo */
4438                         data_size = 0;
4439                         break;
4440
4441                 case SMB_INFO_QUERY_EAS_FROM_LIST:
4442                 {
4443                         size_t total_ea_len = 0;
4444                         struct ea_list *ea_file_list = NULL;
4445
4446                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
4447
4448                         ea_file_list =
4449                             get_ea_list_from_file(mem_ctx, conn, fsp,
4450                                                   smb_fname->base_name,
4451                                                   &total_ea_len);
4452                         ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
4453
4454                         if (!ea_list || (total_ea_len > data_size)) {
4455                                 data_size = 4;
4456                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
4457                                 break;
4458                         }
4459
4460                         data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
4461                         break;
4462                 }
4463
4464                 case SMB_INFO_QUERY_ALL_EAS:
4465                 {
4466                         /* We have data_size bytes to put EA's into. */
4467                         size_t total_ea_len = 0;
4468
4469                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
4470
4471                         ea_list = get_ea_list_from_file(mem_ctx, conn, fsp,
4472                                                         smb_fname->base_name,
4473                                                         &total_ea_len);
4474                         if (!ea_list || (total_ea_len > data_size)) {
4475                                 data_size = 4;
4476                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
4477                                 break;
4478                         }
4479
4480                         data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
4481                         break;
4482                 }
4483
4484                 case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
4485                 {
4486                         /* This is FileFullEaInformation - 0xF which maps to
4487                          * 1015 (decimal) in smbd_do_setfilepathinfo. */
4488
4489                         /* We have data_size bytes to put EA's into. */
4490                         size_t total_ea_len = 0;
4491                         struct ea_list *ea_file_list = NULL;
4492
4493                         DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
4494
4495                         /*TODO: add filtering and index handling */
4496
4497                         ea_file_list =
4498                             get_ea_list_from_file(mem_ctx, conn, fsp,
4499                                                   smb_fname->base_name,
4500                                                   &total_ea_len);
4501                         if (!ea_file_list) {
4502                                 return NT_STATUS_NO_EAS_ON_FILE;
4503                         }
4504
4505                         status = fill_ea_chained_buffer(mem_ctx,
4506                                                         pdata,
4507                                                         data_size,
4508                                                         &data_size,
4509                                                         conn, ea_file_list);
4510                         if (!NT_STATUS_IS_OK(status)) {
4511                                 return status;
4512                         }
4513                         break;
4514                 }
4515
4516                 case SMB_FILE_BASIC_INFORMATION:
4517                 case SMB_QUERY_FILE_BASIC_INFO:
4518
4519                         if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
4520                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
4521                                 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
4522                         } else {
4523                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
4524                                 data_size = 40;
4525                                 SIVAL(pdata,36,0);
4526                         }
4527                         put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
4528                         put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
4529                         put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
4530                         put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
4531                         SIVAL(pdata,32,mode);
4532
4533                         DEBUG(5,("SMB_QFBI - "));
4534                         DEBUG(5,("create: %s ", ctime(&create_time)));
4535                         DEBUG(5,("access: %s ", ctime(&atime)));
4536                         DEBUG(5,("write: %s ", ctime(&mtime)));
4537                         DEBUG(5,("change: %s ", ctime(&c_time)));
4538                         DEBUG(5,("mode: %x\n", mode));
4539                         break;
4540
4541                 case SMB_FILE_STANDARD_INFORMATION:
4542                 case SMB_QUERY_FILE_STANDARD_INFO:
4543
4544                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
4545                         data_size = 24;
4546                         SOFF_T(pdata,0,allocation_size);
4547                         SOFF_T(pdata,8,file_size);
4548                         SIVAL(pdata,16,nlink);
4549                         SCVAL(pdata,20,delete_pending?1:0);
4550                         SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
4551                         SSVAL(pdata,22,0); /* Padding. */
4552                         break;
4553
4554                 case SMB_FILE_EA_INFORMATION:
4555                 case SMB_QUERY_FILE_EA_INFO:
4556                 {
4557                         unsigned int ea_size =
4558                             estimate_ea_size(conn, fsp, smb_fname->base_name);
4559                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
4560                         data_size = 4;
4561                         SIVAL(pdata,0,ea_size);
4562                         break;
4563                 }
4564
4565                 /* Get the 8.3 name - used if NT SMB was negotiated. */
4566                 case SMB_QUERY_FILE_ALT_NAME_INFO:
4567                 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
4568                 {
4569                         int len;
4570                         char mangled_name[13];
4571                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
4572                         if (!name_to_8_3(base_name,mangled_name,
4573                                                 True,conn->params)) {
4574                                 return NT_STATUS_NO_MEMORY;
4575                         }
4576                         len = srvstr_push(dstart, flags2,
4577                                           pdata+4, mangled_name,
4578                                           PTR_DIFF(dend, pdata+4),
4579                                           STR_UNICODE);
4580                         data_size = 4 + len;
4581                         SIVAL(pdata,0,len);
4582                         break;
4583                 }
4584
4585                 case SMB_QUERY_FILE_NAME_INFO:
4586                 {
4587                         int len;
4588                         /*
4589                           this must be *exactly* right for ACLs on mapped drives to work
4590                          */
4591                         len = srvstr_push(dstart, flags2,
4592                                           pdata+4, dos_fname,
4593                                           PTR_DIFF(dend, pdata+4),
4594                                           STR_UNICODE);
4595                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
4596                         data_size = 4 + len;
4597                         SIVAL(pdata,0,len);
4598                         break;
4599                 }
4600
4601                 case SMB_FILE_ALLOCATION_INFORMATION:
4602                 case SMB_QUERY_FILE_ALLOCATION_INFO:
4603                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
4604                         data_size = 8;
4605                         SOFF_T(pdata,0,allocation_size);
4606                         break;
4607
4608                 case SMB_FILE_END_OF_FILE_INFORMATION:
4609                 case SMB_QUERY_FILE_END_OF_FILEINFO:
4610                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
4611                         data_size = 8;
4612                         SOFF_T(pdata,0,file_size);
4613                         break;
4614
4615                 case SMB_QUERY_FILE_ALL_INFO:
4616                 case SMB_FILE_ALL_INFORMATION:
4617                 {
4618                         int len;
4619                         unsigned int ea_size =
4620                             estimate_ea_size(conn, fsp, smb_fname->base_name);
4621                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
4622                         put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
4623                         put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
4624                         put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
4625                         put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
4626                         SIVAL(pdata,32,mode);
4627                         SIVAL(pdata,36,0); /* padding. */
4628                         pdata += 40;
4629                         SOFF_T(pdata,0,allocation_size);
4630                         SOFF_T(pdata,8,file_size);
4631                         SIVAL(pdata,16,nlink);
4632                         SCVAL(pdata,20,delete_pending);
4633                         SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
4634                         SSVAL(pdata,22,0);
4635                         pdata += 24;
4636                         SIVAL(pdata,0,ea_size);
4637                         pdata += 4; /* EA info */
4638                         len = srvstr_push(dstart, flags2,
4639                                           pdata+4, dos_fname,
4640                                           PTR_DIFF(dend, pdata+4),
4641                                           STR_UNICODE);
4642                         SIVAL(pdata,0,len);
4643                         pdata += 4 + len;
4644                         data_size = PTR_DIFF(pdata,(*ppdata));
4645                         break;
4646                 }
4647
4648                 case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
4649                 {
4650                         int len;
4651                         unsigned int ea_size =
4652                             estimate_ea_size(conn, fsp, smb_fname->base_name);
4653                         DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
4654                         put_long_date_timespec(conn->ts_res,pdata+0x00,create_time_ts);
4655                         put_long_date_timespec(conn->ts_res,pdata+0x08,atime_ts);
4656                         put_long_date_timespec(conn->ts_res,pdata+0x10,mtime_ts); /* write time */
4657                         put_long_date_timespec(conn->ts_res,pdata+0x18,ctime_ts); /* change time */
4658                         SIVAL(pdata,    0x20, mode);
4659                         SIVAL(pdata,    0x24, 0); /* padding. */
4660                         SBVAL(pdata,    0x28, allocation_size);
4661                         SBVAL(pdata,    0x30, file_size);
4662                         SIVAL(pdata,    0x38, nlink);
4663                         SCVAL(pdata,    0x3C, delete_pending);
4664                         SCVAL(pdata,    0x3D, (mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
4665                         SSVAL(pdata,    0x3E, 0); /* padding */
4666                         SBVAL(pdata,    0x40, file_index);
4667                         SIVAL(pdata,    0x48, ea_size);
4668                         SIVAL(pdata,    0x4C, access_mask);
4669                         SBVAL(pdata,    0x50, pos);
4670                         SIVAL(pdata,    0x58, mode); /*TODO: mode != mode fix this!!! */
4671                         SIVAL(pdata,    0x5C, 0); /* No alignment needed. */
4672
4673                         pdata += 0x60;
4674
4675                         len = srvstr_push(dstart, flags2,
4676                                           pdata+4, dos_fname,
4677                                           PTR_DIFF(dend, pdata+4),
4678                                           STR_UNICODE);
4679                         SIVAL(pdata,0,len);
4680                         pdata += 4 + len;
4681                         data_size = PTR_DIFF(pdata,(*ppdata));
4682                         break;
4683                 }
4684                 case SMB_FILE_INTERNAL_INFORMATION:
4685
4686                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
4687                         SBVAL(pdata, 0, file_index);
4688                         data_size = 8;
4689                         break;
4690
4691                 case SMB_FILE_ACCESS_INFORMATION:
4692                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
4693                         SIVAL(pdata, 0, access_mask);
4694                         data_size = 4;
4695                         break;
4696
4697                 case SMB_FILE_NAME_INFORMATION:
4698                         /* Pathname with leading '\'. */
4699                         {
4700                                 size_t byte_len;
4701                                 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
4702                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
4703                                 SIVAL(pdata,0,byte_len);
4704                                 data_size = 4 + byte_len;
4705                                 break;
4706                         }
4707
4708                 case SMB_FILE_DISPOSITION_INFORMATION:
4709                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
4710                         data_size = 1;
4711                         SCVAL(pdata,0,delete_pending);
4712                         break;
4713
4714                 case SMB_FILE_POSITION_INFORMATION:
4715                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
4716                         data_size = 8;
4717                         SOFF_T(pdata,0,pos);
4718                         break;
4719
4720                 case SMB_FILE_MODE_INFORMATION:
4721                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
4722                         SIVAL(pdata,0,mode);
4723                         data_size = 4;
4724                         break;
4725
4726                 case SMB_FILE_ALIGNMENT_INFORMATION:
4727                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
4728                         SIVAL(pdata,0,0); /* No alignment needed. */
4729                         data_size = 4;
4730                         break;
4731
4732                 /*
4733                  * NT4 server just returns "invalid query" to this - if we try
4734                  * to answer it then NTws gets a BSOD! (tridge).  W2K seems to
4735                  * want this. JRA.
4736                  */
4737                 /* The first statement above is false - verified using Thursby
4738                  * client against NT4 -- gcolley.
4739                  */
4740                 case SMB_QUERY_FILE_STREAM_INFO:
4741                 case SMB_FILE_STREAM_INFORMATION: {
4742                         unsigned int num_streams = 0;
4743                         struct stream_struct *streams = NULL;
4744
4745                         DEBUG(10,("smbd_do_qfilepathinfo: "
4746                                   "SMB_FILE_STREAM_INFORMATION\n"));
4747
4748                         if (is_ntfs_stream_smb_fname(smb_fname)) {
4749                                 return NT_STATUS_INVALID_PARAMETER;
4750                         }
4751
4752                         status = vfs_streaminfo(conn, fsp, smb_fname->base_name,
4753                                                 talloc_tos(), &num_streams, &streams);
4754
4755                         if (!NT_STATUS_IS_OK(status)) {
4756                                 DEBUG(10, ("could not get stream info: %s\n",
4757                                            nt_errstr(status)));
4758                                 return status;
4759                         }
4760
4761                         status = marshall_stream_info(num_streams, streams,
4762                                                       pdata, max_data_bytes,
4763                                                       &data_size);
4764
4765                         if (!NT_STATUS_IS_OK(status)) {
4766                                 DEBUG(10, ("marshall_stream_info failed: %s\n",
4767                                            nt_errstr(status)));
4768                                 return status;
4769                         }
4770
4771                         TALLOC_FREE(streams);
4772
4773                         break;
4774                 }
4775                 case SMB_QUERY_COMPRESSION_INFO:
4776                 case SMB_FILE_COMPRESSION_INFORMATION:
4777                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
4778                         SOFF_T(pdata,0,file_size);
4779                         SIVAL(pdata,8,0); /* ??? */
4780                         SIVAL(pdata,12,0); /* ??? */
4781                         data_size = 16;
4782                         break;
4783
4784                 case SMB_FILE_NETWORK_OPEN_INFORMATION:
4785                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
4786                         put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
4787                         put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
4788                         put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
4789                         put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
4790                         SOFF_T(pdata,32,allocation_size);
4791                         SOFF_T(pdata,40,file_size);
4792                         SIVAL(pdata,48,mode);
4793                         SIVAL(pdata,52,0); /* ??? */
4794                         data_size = 56;
4795                         break;
4796
4797                 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
4798                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
4799                         SIVAL(pdata,0,mode);
4800                         SIVAL(pdata,4,0);
4801                         data_size = 8;
4802                         break;
4803
4804                 /*
4805                  * CIFS UNIX Extensions.
4806                  */
4807
4808                 case SMB_QUERY_FILE_UNIX_BASIC:
4809
4810                         pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
4811                         data_size = PTR_DIFF(pdata,(*ppdata));
4812
4813                         DEBUG(4,("smbd_do_qfilepathinfo: "
4814                                  "SMB_QUERY_FILE_UNIX_BASIC\n"));
4815                         dump_data(4, (uint8_t *)(*ppdata), data_size);
4816
4817                         break;
4818
4819                 case SMB_QUERY_FILE_UNIX_INFO2:
4820
4821                         pdata = store_file_unix_basic_info2(conn, pdata, fsp, psbuf);
4822                         data_size = PTR_DIFF(pdata,(*ppdata));
4823
4824                         {
4825                                 int i;
4826                                 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
4827
4828                                 for (i=0; i<100; i++)
4829                                         DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
4830                                 DEBUG(4,("\n"));
4831                         }
4832
4833                         break;
4834
4835                 case SMB_QUERY_FILE_UNIX_LINK:
4836                         {
4837                                 int len;
4838                                 char *buffer = talloc_array(mem_ctx, char, PATH_MAX+1);
4839
4840                                 if (!buffer) {
4841                                         return NT_STATUS_NO_MEMORY;
4842                                 }
4843
4844                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
4845 #ifdef S_ISLNK
4846                                 if(!S_ISLNK(psbuf->st_ex_mode)) {
4847                                         return NT_STATUS_DOS(ERRSRV, ERRbadlink);
4848                                 }
4849 #else
4850                                 return NT_STATUS_DOS(ERRDOS, ERRbadlink);
4851 #endif
4852                                 len = SMB_VFS_READLINK(conn,
4853                                                        smb_fname->base_name,
4854                                                        buffer, PATH_MAX);
4855                                 if (len == -1) {
4856                                         return map_nt_error_from_unix(errno);
4857                                 }
4858                                 buffer[len] = 0;
4859                                 len = srvstr_push(dstart, flags2,
4860                                                   pdata, buffer,
4861                                                   PTR_DIFF(dend, pdata),
4862                                                   STR_TERMINATE);
4863                                 pdata += len;
4864                                 data_size = PTR_DIFF(pdata,(*ppdata));
4865
4866                                 break;
4867                         }
4868
4869 #if defined(HAVE_POSIX_ACLS)
4870                 case SMB_QUERY_POSIX_ACL:
4871                         {
4872                                 SMB_ACL_T file_acl = NULL;
4873                                 SMB_ACL_T def_acl = NULL;
4874                                 uint16 num_file_acls = 0;
4875                                 uint16 num_def_acls = 0;
4876
4877                                 if (fsp && fsp->fh->fd != -1) {
4878                                         file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp);
4879                                 } else {
4880                                         file_acl =
4881                                             SMB_VFS_SYS_ACL_GET_FILE(conn,
4882                                                 smb_fname->base_name,
4883                                                 SMB_ACL_TYPE_ACCESS);
4884                                 }
4885
4886                                 if (file_acl == NULL && no_acl_syscall_error(errno)) {
4887                                         DEBUG(5,("smbd_do_qfilepathinfo: ACLs "
4888                                                  "not implemented on "
4889                                                  "filesystem containing %s\n",
4890                                                  smb_fname->base_name));
4891                                         return NT_STATUS_NOT_IMPLEMENTED;
4892                                 }
4893
4894                                 if (S_ISDIR(psbuf->st_ex_mode)) {
4895                                         if (fsp && fsp->is_directory) {
4896                                                 def_acl =
4897                                                     SMB_VFS_SYS_ACL_GET_FILE(
4898                                                             conn,
4899                                                             fsp->fsp_name->base_name,
4900                                                             SMB_ACL_TYPE_DEFAULT);
4901                                         } else {
4902                                                 def_acl =
4903                                                     SMB_VFS_SYS_ACL_GET_FILE(
4904                                                             conn,
4905                                                             smb_fname->base_name,
4906                                                             SMB_ACL_TYPE_DEFAULT);
4907                                         }
4908                                         def_acl = free_empty_sys_acl(conn, def_acl);
4909                                 }
4910
4911                                 num_file_acls = count_acl_entries(conn, file_acl);
4912                                 num_def_acls = count_acl_entries(conn, def_acl);
4913
4914                                 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
4915                                         DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n",
4916                                                 data_size,
4917                                                 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
4918                                                         SMB_POSIX_ACL_HEADER_SIZE) ));
4919                                         if (file_acl) {
4920                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4921                                         }
4922                                         if (def_acl) {
4923                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4924                                         }
4925                                         return NT_STATUS_BUFFER_TOO_SMALL;
4926                                 }
4927
4928                                 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
4929                                 SSVAL(pdata,2,num_file_acls);
4930                                 SSVAL(pdata,4,num_def_acls);
4931                                 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, psbuf, file_acl)) {
4932                                         if (file_acl) {
4933                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4934                                         }
4935                                         if (def_acl) {
4936                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4937                                         }
4938                                         return NT_STATUS_INTERNAL_ERROR;
4939                                 }
4940                                 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), psbuf, def_acl)) {
4941                                         if (file_acl) {
4942                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4943                                         }
4944                                         if (def_acl) {
4945                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4946                                         }
4947                                         return NT_STATUS_INTERNAL_ERROR;
4948                                 }
4949
4950                                 if (file_acl) {
4951                                         SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4952                                 }
4953                                 if (def_acl) {
4954                                         SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4955                                 }
4956                                 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
4957                                 break;
4958                         }
4959 #endif
4960
4961
4962                 case SMB_QUERY_POSIX_LOCK:
4963                 {
4964                         uint64_t count;
4965                         uint64_t offset;
4966                         uint64_t smblctx;
4967                         enum brl_type lock_type;
4968
4969                         /* We need an open file with a real fd for this. */
4970                         if (!fsp || fsp->fh->fd == -1) {
4971                                 return NT_STATUS_INVALID_LEVEL;
4972                         }
4973
4974                         if (lock_data_count != POSIX_LOCK_DATA_SIZE) {
4975                                 return NT_STATUS_INVALID_PARAMETER;
4976                         }
4977
4978                         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
4979                                 case POSIX_LOCK_TYPE_READ:
4980                                         lock_type = READ_LOCK;
4981                                         break;
4982                                 case POSIX_LOCK_TYPE_WRITE:
4983                                         lock_type = WRITE_LOCK;
4984                                         break;
4985                                 case POSIX_LOCK_TYPE_UNLOCK:
4986                                 default:
4987                                         /* There's no point in asking for an unlock... */
4988                                         return NT_STATUS_INVALID_PARAMETER;
4989                         }
4990
4991                         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
4992 #if defined(HAVE_LONGLONG)
4993                         offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
4994                                         ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
4995                         count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
4996                                         ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
4997 #else /* HAVE_LONGLONG */
4998                         offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET);
4999                         count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
5000 #endif /* HAVE_LONGLONG */
5001
5002                         status = query_lock(fsp,
5003                                         &smblctx,
5004                                         &count,
5005                                         &offset,
5006                                         &lock_type,
5007                                         POSIX_LOCK);
5008
5009                         if (ERROR_WAS_LOCK_DENIED(status)) {
5010                                 /* Here we need to report who has it locked... */
5011                                 data_size = POSIX_LOCK_DATA_SIZE;
5012
5013                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
5014                                 SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
5015                                 SIVAL(pdata, POSIX_LOCK_PID_OFFSET, (uint32_t)smblctx);
5016 #if defined(HAVE_LONGLONG)
5017                                 SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF));
5018                                 SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF));
5019                                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF));
5020                                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF));
5021 #else /* HAVE_LONGLONG */
5022                                 SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
5023                                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
5024 #endif /* HAVE_LONGLONG */
5025
5026                         } else if (NT_STATUS_IS_OK(status)) {
5027                                 /* For success we just return a copy of what we sent
5028                                    with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
5029                                 data_size = POSIX_LOCK_DATA_SIZE;
5030                                 memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
5031                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
5032                         } else {
5033                                 return status;
5034                         }
5035                         break;
5036                 }
5037
5038                 default:
5039                         return NT_STATUS_INVALID_LEVEL;
5040         }
5041
5042         *pdata_size = data_size;
5043         return NT_STATUS_OK;
5044 }
5045
5046 /****************************************************************************
5047  Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
5048  file name or file id).
5049 ****************************************************************************/
5050
5051 static void call_trans2qfilepathinfo(connection_struct *conn,
5052                                      struct smb_request *req,
5053                                      unsigned int tran_call,
5054                                      char **pparams, int total_params,
5055                                      char **ppdata, int total_data,
5056                                      unsigned int max_data_bytes)
5057 {
5058         char *params = *pparams;
5059         char *pdata = *ppdata;
5060         uint16 info_level;
5061         unsigned int data_size = 0;
5062         unsigned int param_size = 2;
5063         struct smb_filename *smb_fname = NULL;
5064         bool delete_pending = False;
5065         struct timespec write_time_ts;
5066         files_struct *fsp = NULL;
5067         struct file_id fileid;
5068         struct ea_list *ea_list = NULL;
5069         int lock_data_count = 0;
5070         char *lock_data = NULL;
5071         NTSTATUS status = NT_STATUS_OK;
5072
5073         if (!params) {
5074                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5075                 return;
5076         }
5077
5078         ZERO_STRUCT(write_time_ts);
5079
5080         if (tran_call == TRANSACT2_QFILEINFO) {
5081                 if (total_params < 4) {
5082                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5083                         return;
5084                 }
5085
5086                 if (IS_IPC(conn)) {
5087                         call_trans2qpipeinfo(conn, req, tran_call,
5088                                              pparams, total_params,
5089                                              ppdata, total_data,
5090                                              max_data_bytes);
5091                         return;
5092                 }
5093
5094                 fsp = file_fsp(req, SVAL(params,0));
5095                 info_level = SVAL(params,2);
5096
5097                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
5098
5099                 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
5100                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5101                         return;
5102                 }
5103
5104                 /* Initial check for valid fsp ptr. */
5105                 if (!check_fsp_open(conn, req, fsp)) {
5106                         return;
5107                 }
5108
5109                 status = copy_smb_filename(talloc_tos(), fsp->fsp_name,
5110                                            &smb_fname);
5111                 if (!NT_STATUS_IS_OK(status)) {
5112                         reply_nterror(req, status);
5113                         return;
5114                 }
5115
5116                 if(fsp->fake_file_handle) {
5117                         /*
5118                          * This is actually for the QUOTA_FAKE_FILE --metze
5119                          */
5120
5121                         /* We know this name is ok, it's already passed the checks. */
5122
5123                 } else if(fsp->fh->fd == -1) {
5124                         /*
5125                          * This is actually a QFILEINFO on a directory
5126                          * handle (returned from an NT SMB). NT5.0 seems
5127                          * to do this call. JRA.
5128                          */
5129
5130                         if (INFO_LEVEL_IS_UNIX(info_level)) {
5131                                 /* Always do lstat for UNIX calls. */
5132                                 if (SMB_VFS_LSTAT(conn, smb_fname)) {
5133                                         DEBUG(3,("call_trans2qfilepathinfo: "
5134                                                  "SMB_VFS_LSTAT of %s failed "
5135                                                  "(%s)\n",
5136                                                  smb_fname_str_dbg(smb_fname),
5137                                                  strerror(errno)));
5138                                         reply_nterror(req,
5139                                                 map_nt_error_from_unix(errno));
5140                                         return;
5141                                 }
5142                         } else if (SMB_VFS_STAT(conn, smb_fname)) {
5143                                 DEBUG(3,("call_trans2qfilepathinfo: "
5144                                          "SMB_VFS_STAT of %s failed (%s)\n",
5145                                          smb_fname_str_dbg(smb_fname),
5146                                          strerror(errno)));
5147                                 reply_nterror(req,
5148                                         map_nt_error_from_unix(errno));
5149                                 return;
5150                         }
5151
5152                         fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
5153                         get_file_infos(fileid, fsp->name_hash, &delete_pending, &write_time_ts);
5154                 } else {
5155                         /*
5156                          * Original code - this is an open file.
5157                          */
5158                         if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
5159                                 DEBUG(3, ("fstat of fnum %d failed (%s)\n",
5160                                           fsp->fnum, strerror(errno)));
5161                                 reply_nterror(req,
5162                                         map_nt_error_from_unix(errno));
5163                                 return;
5164                         }
5165                         fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
5166                         get_file_infos(fileid, fsp->name_hash, &delete_pending, &write_time_ts);
5167                 }
5168
5169         } else {
5170                 uint32_t name_hash;
5171                 char *fname = NULL;
5172                 uint32_t ucf_flags = 0;
5173
5174                 /* qpathinfo */
5175                 if (total_params < 7) {
5176                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5177                         return;
5178                 }
5179
5180                 info_level = SVAL(params,0);
5181
5182                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
5183
5184                 if (INFO_LEVEL_IS_UNIX(info_level)) {
5185                         if (!lp_unix_extensions()) {
5186                                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5187                                 return;
5188                         }
5189                         if (info_level == SMB_QUERY_FILE_UNIX_BASIC ||
5190                                         info_level == SMB_QUERY_FILE_UNIX_INFO2 ||
5191                                         info_level == SMB_QUERY_FILE_UNIX_LINK) {
5192                                 ucf_flags |= UCF_UNIX_NAME_LOOKUP;
5193                         }
5194                 }
5195
5196                 srvstr_get_path(req, params, req->flags2, &fname, &params[6],
5197                                 total_params - 6,
5198                                 STR_TERMINATE, &status);
5199                 if (!NT_STATUS_IS_OK(status)) {
5200                         reply_nterror(req, status);
5201                         return;
5202                 }
5203
5204                 status = filename_convert(req,
5205                                         conn,
5206                                         req->flags2 & FLAGS2_DFS_PATHNAMES,
5207                                         fname,
5208                                         ucf_flags,
5209                                         NULL,
5210                                         &smb_fname);
5211                 if (!NT_STATUS_IS_OK(status)) {
5212                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5213                                 reply_botherror(req,
5214                                                 NT_STATUS_PATH_NOT_COVERED,
5215                                                 ERRSRV, ERRbadpath);
5216                                 return;
5217                         }
5218                         reply_nterror(req, status);
5219                         return;
5220                 }
5221
5222                 /* If this is a stream, check if there is a delete_pending. */
5223                 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5224                     && is_ntfs_stream_smb_fname(smb_fname)) {
5225                         struct smb_filename *smb_fname_base = NULL;
5226
5227                         /* Create an smb_filename with stream_name == NULL. */
5228                         status =
5229                             create_synthetic_smb_fname(talloc_tos(),
5230                                                        smb_fname->base_name,
5231                                                        NULL, NULL,
5232                                                        &smb_fname_base);
5233                         if (!NT_STATUS_IS_OK(status)) {
5234                                 reply_nterror(req, status);
5235                                 return;
5236                         }
5237
5238                         if (INFO_LEVEL_IS_UNIX(info_level)) {
5239                                 /* Always do lstat for UNIX calls. */
5240                                 if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
5241                                         DEBUG(3,("call_trans2qfilepathinfo: "
5242                                                  "SMB_VFS_LSTAT of %s failed "
5243                                                  "(%s)\n",
5244                                                  smb_fname_str_dbg(smb_fname_base),
5245                                                  strerror(errno)));
5246                                         TALLOC_FREE(smb_fname_base);
5247                                         reply_nterror(req,
5248                                                 map_nt_error_from_unix(errno));
5249                                         return;
5250                                 }
5251                         } else {
5252                                 if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
5253                                         DEBUG(3,("call_trans2qfilepathinfo: "
5254                                                  "fileinfo of %s failed "
5255                                                  "(%s)\n",
5256                                                  smb_fname_str_dbg(smb_fname_base),
5257                                                  strerror(errno)));
5258                                         TALLOC_FREE(smb_fname_base);
5259                                         reply_nterror(req,
5260                                                 map_nt_error_from_unix(errno));
5261                                         return;
5262                                 }
5263                         }
5264
5265                         status = file_name_hash(conn,
5266                                         smb_fname_str_dbg(smb_fname_base),
5267                                         &name_hash);
5268                         if (!NT_STATUS_IS_OK(status)) {
5269                                 TALLOC_FREE(smb_fname_base);
5270                                 reply_nterror(req, status);
5271                                 return;
5272                         }
5273
5274                         fileid = vfs_file_id_from_sbuf(conn,
5275                                                        &smb_fname_base->st);
5276                         TALLOC_FREE(smb_fname_base);
5277                         get_file_infos(fileid, name_hash, &delete_pending, NULL);
5278                         if (delete_pending) {
5279                                 reply_nterror(req, NT_STATUS_DELETE_PENDING);
5280                                 return;
5281                         }
5282                 }
5283
5284                 if (INFO_LEVEL_IS_UNIX(info_level)) {
5285                         /* Always do lstat for UNIX calls. */
5286                         if (SMB_VFS_LSTAT(conn, smb_fname)) {
5287                                 DEBUG(3,("call_trans2qfilepathinfo: "
5288                                          "SMB_VFS_LSTAT of %s failed (%s)\n",
5289                                          smb_fname_str_dbg(smb_fname),
5290                                          strerror(errno)));
5291                                 reply_nterror(req,
5292                                         map_nt_error_from_unix(errno));
5293                                 return;
5294                         }
5295
5296                 } else {
5297                         if (SMB_VFS_STAT(conn, smb_fname) != 0) {
5298                                 DEBUG(3,("call_trans2qfilepathinfo: "
5299                                          "SMB_VFS_STAT of %s failed (%s)\n",
5300                                          smb_fname_str_dbg(smb_fname),
5301                                          strerror(errno)));
5302                                 reply_nterror(req,
5303                                         map_nt_error_from_unix(errno));
5304                                 return;
5305                         }
5306                 }
5307
5308                 status = file_name_hash(conn,
5309                                 smb_fname_str_dbg(smb_fname),
5310                                 &name_hash);
5311                 if (!NT_STATUS_IS_OK(status)) {
5312                         reply_nterror(req, status);
5313                         return;
5314                 }
5315
5316                 fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
5317                 get_file_infos(fileid, name_hash, &delete_pending, &write_time_ts);
5318                 if (delete_pending) {
5319                         reply_nterror(req, NT_STATUS_DELETE_PENDING);
5320                         return;
5321                 }
5322         }
5323
5324         DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d "
5325                  "total_data=%d\n", smb_fname_str_dbg(smb_fname),
5326                  fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
5327
5328         /* Pull out any data sent here before we realloc. */
5329         switch (info_level) {
5330                 case SMB_INFO_QUERY_EAS_FROM_LIST:
5331                 {
5332                         /* Pull any EA list from the data portion. */
5333                         uint32 ea_size;
5334
5335                         if (total_data < 4) {
5336                                 reply_nterror(
5337                                         req, NT_STATUS_INVALID_PARAMETER);
5338                                 return;
5339                         }
5340                         ea_size = IVAL(pdata,0);
5341
5342                         if (total_data > 0 && ea_size != total_data) {
5343                                 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
5344 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
5345                                 reply_nterror(
5346                                         req, NT_STATUS_INVALID_PARAMETER);
5347                                 return;
5348                         }
5349
5350                         if (!lp_ea_support(SNUM(conn))) {
5351                                 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
5352                                 return;
5353                         }
5354
5355                         /* Pull out the list of names. */
5356                         ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4);
5357                         if (!ea_list) {
5358                                 reply_nterror(
5359                                         req, NT_STATUS_INVALID_PARAMETER);
5360                                 return;
5361                         }
5362                         break;
5363                 }
5364
5365                 case SMB_QUERY_POSIX_LOCK:
5366                 {
5367                         if (fsp == NULL || fsp->fh->fd == -1) {
5368                                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
5369                                 return;
5370                         }
5371
5372                         if (total_data != POSIX_LOCK_DATA_SIZE) {
5373                                 reply_nterror(
5374                                         req, NT_STATUS_INVALID_PARAMETER);
5375                                 return;
5376                         }
5377
5378                         /* Copy the lock range data. */
5379                         lock_data = (char *)talloc_memdup(
5380                                 req, pdata, total_data);
5381                         if (!lock_data) {
5382                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
5383                                 return;
5384                         }
5385                         lock_data_count = total_data;
5386                 }
5387                 default:
5388                         break;
5389         }
5390
5391         *pparams = (char *)SMB_REALLOC(*pparams,2);
5392         if (*pparams == NULL) {
5393                 reply_nterror(req, NT_STATUS_NO_MEMORY);
5394                 return;
5395         }
5396         params = *pparams;
5397         SSVAL(params,0,0);
5398
5399         /*
5400          * draft-leach-cifs-v1-spec-02.txt
5401          * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
5402          * says:
5403          *
5404          *  The requested information is placed in the Data portion of the
5405          *  transaction response. For the information levels greater than 0x100,
5406          *  the transaction response has 1 parameter word which should be
5407          *  ignored by the client.
5408          *
5409          * However Windows only follows this rule for the IS_NAME_VALID call.
5410          */
5411         switch (info_level) {
5412         case SMB_INFO_IS_NAME_VALID:
5413                 param_size = 0;
5414                 break;
5415         }
5416
5417         if ((info_level & 0xFF00) == 0xFF00) {
5418                 /*
5419                  * We use levels that start with 0xFF00
5420                  * internally to represent SMB2 specific levels
5421                  */
5422                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5423                 return;
5424         }
5425
5426         status = smbd_do_qfilepathinfo(conn, req, info_level,
5427                                        fsp, smb_fname,
5428                                        delete_pending, write_time_ts,
5429                                        ea_list,
5430                                        lock_data_count, lock_data,
5431                                        req->flags2, max_data_bytes,
5432                                        ppdata, &data_size);
5433         if (!NT_STATUS_IS_OK(status)) {
5434                 reply_nterror(req, status);
5435                 return;
5436         }
5437
5438         send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
5439                             max_data_bytes);
5440
5441         return;
5442 }
5443
5444 /****************************************************************************
5445  Set a hard link (called by UNIX extensions and by NT rename with HARD link
5446  code.
5447 ****************************************************************************/
5448
5449 NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
5450                 connection_struct *conn,
5451                 struct smb_request *req,
5452                 bool overwrite_if_exists,
5453                 const struct smb_filename *smb_fname_old,
5454                 struct smb_filename *smb_fname_new)
5455 {
5456         NTSTATUS status = NT_STATUS_OK;
5457
5458         /* source must already exist. */
5459         if (!VALID_STAT(smb_fname_old->st)) {
5460                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5461         }
5462
5463         if (VALID_STAT(smb_fname_new->st)) {
5464                 if (overwrite_if_exists) {
5465                         if (S_ISDIR(smb_fname_new->st.st_ex_mode)) {
5466                                 return NT_STATUS_FILE_IS_A_DIRECTORY;
5467                         }
5468                         status = unlink_internals(conn,
5469                                                 req,
5470                                                 FILE_ATTRIBUTE_NORMAL,
5471                                                 smb_fname_new,
5472                                                 false);
5473                         if (!NT_STATUS_IS_OK(status)) {
5474                                 return status;
5475                         }
5476                 } else {
5477                         /* Disallow if newname already exists. */
5478                         return NT_STATUS_OBJECT_NAME_COLLISION;
5479                 }
5480         }
5481
5482         /* No links from a directory. */
5483         if (S_ISDIR(smb_fname_old->st.st_ex_mode)) {
5484                 return NT_STATUS_FILE_IS_A_DIRECTORY;
5485         }
5486
5487         /* Setting a hardlink to/from a stream isn't currently supported. */
5488         if (is_ntfs_stream_smb_fname(smb_fname_old) ||
5489             is_ntfs_stream_smb_fname(smb_fname_new)) {
5490                 return NT_STATUS_INVALID_PARAMETER;
5491         }
5492
5493         DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
5494                   smb_fname_old->base_name, smb_fname_new->base_name));
5495
5496         if (SMB_VFS_LINK(conn, smb_fname_old->base_name,
5497                          smb_fname_new->base_name) != 0) {
5498                 status = map_nt_error_from_unix(errno);
5499                 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
5500                          nt_errstr(status), smb_fname_old->base_name,
5501                          smb_fname_new->base_name));
5502         }
5503         return status;
5504 }
5505
5506 /****************************************************************************
5507  Deal with setting the time from any of the setfilepathinfo functions.
5508  NOTE !!!! The check for FILE_WRITE_ATTRIBUTES access must be done *before*
5509  calling this function.
5510 ****************************************************************************/
5511
5512 NTSTATUS smb_set_file_time(connection_struct *conn,
5513                            files_struct *fsp,
5514                            const struct smb_filename *smb_fname,
5515                            struct smb_file_time *ft,
5516                            bool setting_write_time)
5517 {
5518         struct smb_filename smb_fname_base;
5519         uint32 action =
5520                 FILE_NOTIFY_CHANGE_LAST_ACCESS
5521                 |FILE_NOTIFY_CHANGE_LAST_WRITE
5522                 |FILE_NOTIFY_CHANGE_CREATION;
5523
5524         if (!VALID_STAT(smb_fname->st)) {
5525                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5526         }
5527
5528         /* get some defaults (no modifications) if any info is zero or -1. */
5529         if (null_timespec(ft->create_time)) {
5530                 action &= ~FILE_NOTIFY_CHANGE_CREATION;
5531         }
5532
5533         if (null_timespec(ft->atime)) {
5534                 action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
5535         }
5536
5537         if (null_timespec(ft->mtime)) {
5538                 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
5539         }
5540
5541         if (!setting_write_time) {
5542                 /* ft->mtime comes from change time, not write time. */
5543                 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
5544         }
5545
5546         /* Ensure the resolution is the correct for
5547          * what we can store on this filesystem. */
5548
5549         round_timespec(conn->ts_res, &ft->create_time);
5550         round_timespec(conn->ts_res, &ft->ctime);
5551         round_timespec(conn->ts_res, &ft->atime);
5552         round_timespec(conn->ts_res, &ft->mtime);
5553
5554         DEBUG(5,("smb_set_filetime: actime: %s\n ",
5555                 time_to_asc(convert_timespec_to_time_t(ft->atime))));
5556         DEBUG(5,("smb_set_filetime: modtime: %s\n ",
5557                 time_to_asc(convert_timespec_to_time_t(ft->mtime))));
5558         DEBUG(5,("smb_set_filetime: ctime: %s\n ",
5559                 time_to_asc(convert_timespec_to_time_t(ft->ctime))));
5560         DEBUG(5,("smb_set_file_time: createtime: %s\n ",
5561                 time_to_asc(convert_timespec_to_time_t(ft->create_time))));
5562
5563         if (setting_write_time) {
5564                 /*
5565                  * This was a Windows setfileinfo on an open file.
5566                  * NT does this a lot. We also need to 
5567                  * set the time here, as it can be read by 
5568                  * FindFirst/FindNext and with the patch for bug #2045
5569                  * in smbd/fileio.c it ensures that this timestamp is
5570                  * kept sticky even after a write. We save the request
5571                  * away and will set it on file close and after a write. JRA.
5572                  */
5573
5574                 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
5575                           time_to_asc(convert_timespec_to_time_t(ft->mtime))));
5576
5577                 if (fsp != NULL) {
5578                         if (fsp->base_fsp) {
5579                                 set_sticky_write_time_fsp(fsp->base_fsp,
5580                                                           ft->mtime);
5581                         } else {
5582                                 set_sticky_write_time_fsp(fsp, ft->mtime);
5583                         }
5584                 } else {
5585                         set_sticky_write_time_path(
5586                                 vfs_file_id_from_sbuf(conn, &smb_fname->st),
5587                                 ft->mtime);
5588                 }
5589         }
5590
5591         DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
5592
5593         /* Always call ntimes on the base, even if a stream was passed in. */
5594         smb_fname_base = *smb_fname;
5595         smb_fname_base.stream_name = NULL;
5596
5597         if(file_ntimes(conn, &smb_fname_base, ft)!=0) {
5598                 return map_nt_error_from_unix(errno);
5599         }
5600
5601         notify_fname(conn, NOTIFY_ACTION_MODIFIED, action,
5602                      smb_fname->base_name);
5603         return NT_STATUS_OK;
5604 }
5605
5606 /****************************************************************************
5607  Deal with setting the dosmode from any of the setfilepathinfo functions.
5608  NB. The check for FILE_WRITE_ATTRIBUTES access on this path must have been
5609  done before calling this function.
5610 ****************************************************************************/
5611
5612 static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
5613                                      const struct smb_filename *smb_fname,
5614                                      uint32 dosmode)
5615 {
5616         struct smb_filename *smb_fname_base = NULL;
5617         NTSTATUS status;
5618
5619         if (!VALID_STAT(smb_fname->st)) {
5620                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5621         }
5622
5623         /* Always operate on the base_name, even if a stream was passed in. */
5624         status = create_synthetic_smb_fname(talloc_tos(), smb_fname->base_name,
5625                                             NULL, &smb_fname->st,
5626                                             &smb_fname_base);
5627         if (!NT_STATUS_IS_OK(status)) {
5628                 return status;
5629         }
5630
5631         if (dosmode) {
5632                 if (S_ISDIR(smb_fname_base->st.st_ex_mode)) {
5633                         dosmode |= FILE_ATTRIBUTE_DIRECTORY;
5634                 } else {
5635                         dosmode &= ~FILE_ATTRIBUTE_DIRECTORY;
5636                 }
5637         }
5638
5639         DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode));
5640
5641         /* check the mode isn't different, before changing it */
5642         if ((dosmode != 0) && (dosmode != dos_mode(conn, smb_fname_base))) {
5643                 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
5644                           "0x%x\n", smb_fname_str_dbg(smb_fname_base),
5645                           (unsigned int)dosmode));
5646
5647                 if(file_set_dosmode(conn, smb_fname_base, dosmode, NULL,
5648                                     false)) {
5649                         DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
5650                                  "%s failed (%s)\n",
5651                                  smb_fname_str_dbg(smb_fname_base),
5652                                  strerror(errno)));
5653                         status = map_nt_error_from_unix(errno);
5654                         goto out;
5655                 }
5656         }
5657         status = NT_STATUS_OK;
5658  out:
5659         TALLOC_FREE(smb_fname_base);
5660         return status;
5661 }
5662
5663 /****************************************************************************
5664  Deal with setting the size from any of the setfilepathinfo functions.
5665 ****************************************************************************/
5666
5667 static NTSTATUS smb_set_file_size(connection_struct *conn,
5668                                   struct smb_request *req,
5669                                   files_struct *fsp,
5670                                   const struct smb_filename *smb_fname,
5671                                   const SMB_STRUCT_STAT *psbuf,
5672                                   off_t size,
5673                                   bool fail_after_createfile)
5674 {
5675         NTSTATUS status = NT_STATUS_OK;
5676         struct smb_filename *smb_fname_tmp = NULL;
5677         files_struct *new_fsp = NULL;
5678
5679         if (!VALID_STAT(*psbuf)) {
5680                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5681         }
5682
5683         DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size));
5684
5685         if (size == get_file_size_stat(psbuf)) {
5686                 return NT_STATUS_OK;
5687         }
5688
5689         DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
5690                   smb_fname_str_dbg(smb_fname), (double)size));
5691
5692         if (fsp && fsp->fh->fd != -1) {
5693                 /* Handle based call. */
5694                 if (!(fsp->access_mask & FILE_WRITE_DATA)) {
5695                         return NT_STATUS_ACCESS_DENIED;
5696                 }
5697
5698                 if (vfs_set_filelen(fsp, size) == -1) {
5699                         return map_nt_error_from_unix(errno);
5700                 }
5701                 trigger_write_time_update_immediate(fsp);
5702                 return NT_STATUS_OK;
5703         }
5704
5705         status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp);
5706         if (!NT_STATUS_IS_OK(status)) {
5707                 return status;
5708         }
5709
5710         smb_fname_tmp->st = *psbuf;
5711
5712         status = SMB_VFS_CREATE_FILE(
5713                 conn,                                   /* conn */
5714                 req,                                    /* req */
5715                 0,                                      /* root_dir_fid */
5716                 smb_fname_tmp,                          /* fname */
5717                 FILE_WRITE_DATA,                        /* access_mask */
5718                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
5719                     FILE_SHARE_DELETE),
5720                 FILE_OPEN,                              /* create_disposition*/
5721                 0,                                      /* create_options */
5722                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
5723                 FORCE_OPLOCK_BREAK_TO_NONE,             /* oplock_request */
5724                 0,                                      /* allocation_size */
5725                 0,                                      /* private_flags */
5726                 NULL,                                   /* sd */
5727                 NULL,                                   /* ea_list */
5728                 &new_fsp,                               /* result */
5729                 NULL);                                  /* pinfo */
5730
5731         TALLOC_FREE(smb_fname_tmp);
5732
5733         if (!NT_STATUS_IS_OK(status)) {
5734                 /* NB. We check for open_was_deferred in the caller. */
5735                 return status;
5736         }
5737
5738         /* See RAW-SFILEINFO-END-OF-FILE */
5739         if (fail_after_createfile) {
5740                 close_file(req, new_fsp,NORMAL_CLOSE);
5741                 return NT_STATUS_INVALID_LEVEL;
5742         }
5743
5744         if (vfs_set_filelen(new_fsp, size) == -1) {
5745                 status = map_nt_error_from_unix(errno);
5746                 close_file(req, new_fsp,NORMAL_CLOSE);
5747                 return status;
5748         }
5749
5750         trigger_write_time_update_immediate(new_fsp);
5751         close_file(req, new_fsp,NORMAL_CLOSE);
5752         return NT_STATUS_OK;
5753 }
5754
5755 /****************************************************************************
5756  Deal with SMB_INFO_SET_EA.
5757 ****************************************************************************/
5758
5759 static NTSTATUS smb_info_set_ea(connection_struct *conn,
5760                                 const char *pdata,
5761                                 int total_data,
5762                                 files_struct *fsp,
5763                                 const struct smb_filename *smb_fname)
5764 {
5765         struct ea_list *ea_list = NULL;
5766         TALLOC_CTX *ctx = NULL;
5767         NTSTATUS status = NT_STATUS_OK;
5768
5769         if (total_data < 10) {
5770
5771                 /* OS/2 workplace shell seems to send SET_EA requests of "null"
5772                    length. They seem to have no effect. Bug #3212. JRA */
5773
5774                 if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
5775                         /* We're done. We only get EA info in this call. */
5776                         return NT_STATUS_OK;
5777                 }
5778
5779                 return NT_STATUS_INVALID_PARAMETER;
5780         }
5781
5782         if (IVAL(pdata,0) > total_data) {
5783                 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
5784                         IVAL(pdata,0), (unsigned int)total_data));
5785                 return NT_STATUS_INVALID_PARAMETER;
5786         }
5787
5788         ctx = talloc_tos();
5789         ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
5790         if (!ea_list) {
5791                 return NT_STATUS_INVALID_PARAMETER;
5792         }
5793
5794         status = set_ea(conn, fsp, smb_fname, ea_list);
5795
5796         return status;
5797 }
5798
5799 /****************************************************************************
5800  Deal with SMB_FILE_FULL_EA_INFORMATION set.
5801 ****************************************************************************/
5802
5803 static NTSTATUS smb_set_file_full_ea_info(connection_struct *conn,
5804                                 const char *pdata,
5805                                 int total_data,
5806                                 files_struct *fsp)
5807 {
5808         struct ea_list *ea_list = NULL;
5809         NTSTATUS status;
5810
5811         if (!fsp) {
5812                 return NT_STATUS_INVALID_HANDLE;
5813         }
5814
5815         if (!lp_ea_support(SNUM(conn))) {
5816                 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
5817                         "EA's not supported.\n",
5818                         (unsigned int)total_data));
5819                 return NT_STATUS_EAS_NOT_SUPPORTED;
5820         }
5821
5822         if (total_data < 10) {
5823                 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
5824                         "too small.\n",
5825                         (unsigned int)total_data));
5826                 return NT_STATUS_INVALID_PARAMETER;
5827         }
5828
5829         ea_list = read_nttrans_ea_list(talloc_tos(),
5830                                 pdata,
5831                                 total_data);
5832
5833         if (!ea_list) {
5834                 return NT_STATUS_INVALID_PARAMETER;
5835         }
5836
5837         status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
5838
5839         DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
5840                 smb_fname_str_dbg(fsp->fsp_name),
5841                 nt_errstr(status) ));
5842
5843         return status;
5844 }
5845
5846
5847 /****************************************************************************
5848  Deal with SMB_SET_FILE_DISPOSITION_INFO.
5849 ****************************************************************************/
5850
5851 static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
5852                                 const char *pdata,
5853                                 int total_data,
5854                                 files_struct *fsp,
5855                                 struct smb_filename *smb_fname)
5856 {
5857         NTSTATUS status = NT_STATUS_OK;
5858         bool delete_on_close;
5859         uint32 dosmode = 0;
5860
5861         if (total_data < 1) {
5862                 return NT_STATUS_INVALID_PARAMETER;
5863         }
5864
5865         if (fsp == NULL) {
5866                 return NT_STATUS_INVALID_HANDLE;
5867         }
5868
5869         delete_on_close = (CVAL(pdata,0) ? True : False);
5870         dosmode = dos_mode(conn, smb_fname);
5871
5872         DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
5873                 "delete_on_close = %u\n",
5874                 smb_fname_str_dbg(smb_fname),
5875                 (unsigned int)dosmode,
5876                 (unsigned int)delete_on_close ));
5877
5878         if (delete_on_close) {
5879                 status = can_set_delete_on_close(fsp, dosmode);
5880                 if (!NT_STATUS_IS_OK(status)) {
5881                         return status;
5882                 }
5883         }
5884
5885         /* The set is across all open files on this dev/inode pair. */
5886         if (!set_delete_on_close(fsp, delete_on_close,
5887                                  conn->session_info->security_token,
5888                                  conn->session_info->unix_token)) {
5889                 return NT_STATUS_ACCESS_DENIED;
5890         }
5891         return NT_STATUS_OK;
5892 }
5893
5894 /****************************************************************************
5895  Deal with SMB_FILE_POSITION_INFORMATION.
5896 ****************************************************************************/
5897
5898 static NTSTATUS smb_file_position_information(connection_struct *conn,
5899                                 const char *pdata,
5900                                 int total_data,
5901                                 files_struct *fsp)
5902 {
5903         uint64_t position_information;
5904
5905         if (total_data < 8) {
5906                 return NT_STATUS_INVALID_PARAMETER;
5907         }
5908
5909         if (fsp == NULL) {
5910                 /* Ignore on pathname based set. */
5911                 return NT_STATUS_OK;
5912         }
5913
5914         position_information = (uint64_t)IVAL(pdata,0);
5915         position_information |= (((uint64_t)IVAL(pdata,4)) << 32);
5916
5917         DEBUG(10,("smb_file_position_information: Set file position "
5918                   "information for file %s to %.0f\n", fsp_str_dbg(fsp),
5919                   (double)position_information));
5920         fsp->fh->position_information = position_information;
5921         return NT_STATUS_OK;
5922 }
5923
5924 /****************************************************************************
5925  Deal with SMB_FILE_MODE_INFORMATION.
5926 ****************************************************************************/
5927
5928 static NTSTATUS smb_file_mode_information(connection_struct *conn,
5929                                 const char *pdata,
5930                                 int total_data)
5931 {
5932         uint32 mode;
5933
5934         if (total_data < 4) {
5935                 return NT_STATUS_INVALID_PARAMETER;
5936         }
5937         mode = IVAL(pdata,0);
5938         if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
5939                 return NT_STATUS_INVALID_PARAMETER;
5940         }
5941         return NT_STATUS_OK;
5942 }
5943
5944 /****************************************************************************
5945  Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
5946 ****************************************************************************/
5947
5948 static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
5949                                        struct smb_request *req,
5950                                        const char *pdata,
5951                                        int total_data,
5952                                        const struct smb_filename *smb_fname)
5953 {
5954         char *link_target = NULL;
5955         const char *newname = smb_fname->base_name;
5956         TALLOC_CTX *ctx = talloc_tos();
5957
5958         /* Set a symbolic link. */
5959         /* Don't allow this if follow links is false. */
5960
5961         if (total_data == 0) {
5962                 return NT_STATUS_INVALID_PARAMETER;
5963         }
5964
5965         if (!lp_symlinks(SNUM(conn))) {
5966                 return NT_STATUS_ACCESS_DENIED;
5967         }
5968
5969         srvstr_pull_talloc(ctx, pdata, req->flags2, &link_target, pdata,
5970                     total_data, STR_TERMINATE);
5971
5972         if (!link_target) {
5973                 return NT_STATUS_INVALID_PARAMETER;
5974         }
5975
5976         DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
5977                         newname, link_target ));
5978
5979         if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0) {
5980                 return map_nt_error_from_unix(errno);
5981         }
5982
5983         return NT_STATUS_OK;
5984 }
5985
5986 /****************************************************************************
5987  Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
5988 ****************************************************************************/
5989
5990 static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
5991                                         struct smb_request *req,
5992                                         const char *pdata, int total_data,
5993                                         struct smb_filename *smb_fname_new)
5994 {
5995         char *oldname = NULL;
5996         struct smb_filename *smb_fname_old = NULL;
5997         TALLOC_CTX *ctx = talloc_tos();
5998         NTSTATUS status = NT_STATUS_OK;
5999
6000         /* Set a hard link. */
6001         if (total_data == 0) {
6002                 return NT_STATUS_INVALID_PARAMETER;
6003         }
6004
6005         srvstr_get_path(ctx, pdata, req->flags2, &oldname, pdata,
6006                         total_data, STR_TERMINATE, &status);
6007         if (!NT_STATUS_IS_OK(status)) {
6008                 return status;
6009         }
6010
6011         DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
6012                 smb_fname_str_dbg(smb_fname_new), oldname));
6013
6014         status = filename_convert(ctx,
6015                                 conn,
6016                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
6017                                 oldname,
6018                                 0,
6019                                 NULL,
6020                                 &smb_fname_old);
6021         if (!NT_STATUS_IS_OK(status)) {
6022                 return status;
6023         }
6024
6025         return hardlink_internals(ctx, conn, req, false,
6026                         smb_fname_old, smb_fname_new);
6027 }
6028
6029 /****************************************************************************
6030  Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
6031 ****************************************************************************/
6032
6033 static NTSTATUS smb2_file_rename_information(connection_struct *conn,
6034                                             struct smb_request *req,
6035                                             const char *pdata,
6036                                             int total_data,
6037                                             files_struct *fsp,
6038                                             struct smb_filename *smb_fname_src)
6039 {
6040         bool overwrite;
6041         uint32_t len;
6042         char *newname = NULL;
6043         struct smb_filename *smb_fname_dst = NULL;
6044         NTSTATUS status = NT_STATUS_OK;
6045         TALLOC_CTX *ctx = talloc_tos();
6046
6047         if (!fsp) {
6048                 return NT_STATUS_INVALID_HANDLE;
6049         }
6050
6051         if (total_data < 20) {
6052                 return NT_STATUS_INVALID_PARAMETER;
6053         }
6054
6055         overwrite = (CVAL(pdata,0) ? True : False);
6056         len = IVAL(pdata,16);
6057
6058         if (len > (total_data - 20) || (len == 0)) {
6059                 return NT_STATUS_INVALID_PARAMETER;
6060         }
6061
6062         srvstr_get_path(ctx, pdata, req->flags2, &newname,
6063                                 &pdata[20], len, STR_TERMINATE,
6064                                 &status);
6065         if (!NT_STATUS_IS_OK(status)) {
6066                 return status;
6067         }
6068
6069         DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
6070                                 newname));
6071
6072         status = filename_convert(ctx,
6073                                 conn,
6074                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
6075                                 newname,
6076                                 UCF_SAVE_LCOMP,
6077                                 NULL,
6078                                 &smb_fname_dst);
6079         if (!NT_STATUS_IS_OK(status)) {
6080                 return status;
6081         }
6082
6083         if (fsp->base_fsp) {
6084                 /* newname must be a stream name. */
6085                 if (newname[0] != ':') {
6086                         return NT_STATUS_NOT_SUPPORTED;
6087                 }
6088
6089                 /* Create an smb_fname to call rename_internals_fsp() with. */
6090                 status = create_synthetic_smb_fname(talloc_tos(),
6091                     fsp->base_fsp->fsp_name->base_name, newname, NULL,
6092                     &smb_fname_dst);
6093                 if (!NT_STATUS_IS_OK(status)) {
6094                         goto out;
6095                 }
6096
6097                 /*
6098                  * Set the original last component, since
6099                  * rename_internals_fsp() requires it.
6100                  */
6101                 smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
6102                                                               newname);
6103                 if (smb_fname_dst->original_lcomp == NULL) {
6104                         status = NT_STATUS_NO_MEMORY;
6105                         goto out;
6106                 }
6107
6108         }
6109
6110         DEBUG(10,("smb2_file_rename_information: "
6111                   "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
6112                   fsp->fnum, fsp_str_dbg(fsp),
6113                   smb_fname_str_dbg(smb_fname_dst)));
6114         status = rename_internals_fsp(conn, fsp, smb_fname_dst,
6115                                 (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM),
6116                                 overwrite);
6117
6118  out:
6119         TALLOC_FREE(smb_fname_dst);
6120         return status;
6121 }
6122
6123 static NTSTATUS smb_file_link_information(connection_struct *conn,
6124                                             struct smb_request *req,
6125                                             const char *pdata,
6126                                             int total_data,
6127                                             files_struct *fsp,
6128                                             struct smb_filename *smb_fname_src)
6129 {
6130         bool overwrite;
6131         uint32_t len;
6132         char *newname = NULL;
6133         struct smb_filename *smb_fname_dst = NULL;
6134         NTSTATUS status = NT_STATUS_OK;
6135         TALLOC_CTX *ctx = talloc_tos();
6136
6137         if (!fsp) {
6138                 return NT_STATUS_INVALID_HANDLE;
6139         }
6140
6141         if (total_data < 20) {
6142                 return NT_STATUS_INVALID_PARAMETER;
6143         }
6144
6145         overwrite = (CVAL(pdata,0) ? true : false);
6146         len = IVAL(pdata,16);
6147
6148         if (len > (total_data - 20) || (len == 0)) {
6149                 return NT_STATUS_INVALID_PARAMETER;
6150         }
6151
6152         srvstr_get_path(ctx, pdata, req->flags2, &newname,
6153                                 &pdata[20], len, STR_TERMINATE,
6154                                 &status);
6155         if (!NT_STATUS_IS_OK(status)) {
6156                 return status;
6157         }
6158
6159         DEBUG(10,("smb_file_link_information: got name |%s|\n",
6160                                 newname));
6161
6162         status = filename_convert(ctx,
6163                                 conn,
6164                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
6165                                 newname,
6166                                 UCF_SAVE_LCOMP,
6167                                 NULL,
6168                                 &smb_fname_dst);
6169         if (!NT_STATUS_IS_OK(status)) {
6170                 return status;
6171         }
6172
6173         if (fsp->base_fsp) {
6174                 /* No stream names. */
6175                 return NT_STATUS_NOT_SUPPORTED;
6176         }
6177
6178         DEBUG(10,("smb_file_link_information: "
6179                   "SMB_FILE_LINK_INFORMATION (fnum %d) %s -> %s\n",
6180                   fsp->fnum, fsp_str_dbg(fsp),
6181                   smb_fname_str_dbg(smb_fname_dst)));
6182         status = hardlink_internals(ctx,
6183                                 conn,
6184                                 req,
6185                                 overwrite,
6186                                 fsp->fsp_name,
6187                                 smb_fname_dst);
6188
6189         TALLOC_FREE(smb_fname_dst);
6190         return status;
6191 }
6192
6193 /****************************************************************************
6194  Deal with SMB_FILE_RENAME_INFORMATION.
6195 ****************************************************************************/
6196
6197 static NTSTATUS smb_file_rename_information(connection_struct *conn,
6198                                             struct smb_request *req,
6199                                             const char *pdata,
6200                                             int total_data,
6201                                             files_struct *fsp,
6202                                             struct smb_filename *smb_fname_src)
6203 {
6204         bool overwrite;
6205         uint32 root_fid;
6206         uint32 len;
6207         char *newname = NULL;
6208         struct smb_filename *smb_fname_dst = NULL;
6209         bool dest_has_wcard = False;
6210         NTSTATUS status = NT_STATUS_OK;
6211         char *p;
6212         TALLOC_CTX *ctx = talloc_tos();
6213
6214         if (total_data < 13) {
6215                 return NT_STATUS_INVALID_PARAMETER;
6216         }
6217
6218         overwrite = (CVAL(pdata,0) ? True : False);
6219         root_fid = IVAL(pdata,4);
6220         len = IVAL(pdata,8);
6221
6222         if (len > (total_data - 12) || (len == 0) || (root_fid != 0)) {
6223                 return NT_STATUS_INVALID_PARAMETER;
6224         }
6225
6226         srvstr_get_path_wcard(ctx, pdata, req->flags2, &newname, &pdata[12],
6227                               len, 0, &status,
6228                               &dest_has_wcard);
6229         if (!NT_STATUS_IS_OK(status)) {
6230                 return status;
6231         }
6232
6233         DEBUG(10,("smb_file_rename_information: got name |%s|\n",
6234                                 newname));
6235
6236         status = resolve_dfspath_wcard(ctx, conn,
6237                                        req->flags2 & FLAGS2_DFS_PATHNAMES,
6238                                        newname,
6239                                        true,
6240                                        !conn->sconn->using_smb2,
6241                                        &newname,
6242                                        &dest_has_wcard);
6243         if (!NT_STATUS_IS_OK(status)) {
6244                 return status;
6245         }
6246
6247         /* Check the new name has no '/' characters. */
6248         if (strchr_m(newname, '/')) {
6249                 return NT_STATUS_NOT_SUPPORTED;
6250         }
6251
6252         if (fsp && fsp->base_fsp) {
6253                 /* newname must be a stream name. */
6254                 if (newname[0] != ':') {
6255                         return NT_STATUS_NOT_SUPPORTED;
6256                 }
6257
6258                 /* Create an smb_fname to call rename_internals_fsp() with. */
6259                 status = create_synthetic_smb_fname(talloc_tos(),
6260                     fsp->base_fsp->fsp_name->base_name, newname, NULL,
6261                     &smb_fname_dst);
6262                 if (!NT_STATUS_IS_OK(status)) {
6263                         goto out;
6264                 }
6265
6266                 /*
6267                  * Set the original last component, since
6268                  * rename_internals_fsp() requires it.
6269                  */
6270                 smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
6271                                                               newname);
6272                 if (smb_fname_dst->original_lcomp == NULL) {
6273                         status = NT_STATUS_NO_MEMORY;
6274                         goto out;
6275                 }
6276
6277         } else {
6278                 /*
6279                  * Build up an smb_fname_dst based on the filename passed in.
6280                  * We basically just strip off the last component, and put on
6281                  * the newname instead.
6282                  */
6283                 char *base_name = NULL;
6284
6285                 /* newname must *not* be a stream name. */
6286                 if (newname[0] == ':') {
6287                         return NT_STATUS_NOT_SUPPORTED;
6288                 }
6289
6290                 /*
6291                  * Strip off the last component (filename) of the path passed
6292                  * in.
6293                  */
6294                 base_name = talloc_strdup(ctx, smb_fname_src->base_name);
6295                 if (!base_name) {
6296                         return NT_STATUS_NO_MEMORY;
6297                 }
6298                 p = strrchr_m(base_name, '/');
6299                 if (p) {
6300                         p[1] = '\0';
6301                 } else {
6302                         base_name = talloc_strdup(ctx, "");
6303                         if (!base_name) {
6304                                 return NT_STATUS_NO_MEMORY;
6305                         }
6306                 }
6307                 /* Append the new name. */
6308                 base_name = talloc_asprintf_append(base_name,
6309                                 "%s",
6310                                 newname);
6311                 if (!base_name) {
6312                         return NT_STATUS_NO_MEMORY;
6313                 }
6314
6315                 status = unix_convert(ctx, conn, base_name, &smb_fname_dst,
6316                                       (UCF_SAVE_LCOMP |
6317                                           (dest_has_wcard ?
6318                                               UCF_ALWAYS_ALLOW_WCARD_LCOMP :
6319                                               0)));
6320
6321                 /* If an error we expect this to be
6322                  * NT_STATUS_OBJECT_PATH_NOT_FOUND */
6323
6324                 if (!NT_STATUS_IS_OK(status)) {
6325                         if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND,
6326                                             status)) {
6327                                 goto out;
6328                         }
6329                         /* Create an smb_fname to call rename_internals_fsp() */
6330                         status = create_synthetic_smb_fname(ctx,
6331                                                             base_name, NULL,
6332                                                             NULL,
6333                                                             &smb_fname_dst);
6334                         if (!NT_STATUS_IS_OK(status)) {
6335                                 goto out;
6336                         }
6337                 }
6338         }
6339
6340         if (fsp) {
6341                 DEBUG(10,("smb_file_rename_information: "
6342                           "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
6343                           fsp->fnum, fsp_str_dbg(fsp),
6344                           smb_fname_str_dbg(smb_fname_dst)));
6345                 status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
6346                                               overwrite);
6347         } else {
6348                 DEBUG(10,("smb_file_rename_information: "
6349                           "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
6350                           smb_fname_str_dbg(smb_fname_src),
6351                           smb_fname_str_dbg(smb_fname_dst)));
6352                 status = rename_internals(ctx, conn, req, smb_fname_src,
6353                                           smb_fname_dst, 0, overwrite, false,
6354                                           dest_has_wcard,
6355                                           FILE_WRITE_ATTRIBUTES);
6356         }
6357  out:
6358         TALLOC_FREE(smb_fname_dst);
6359         return status;
6360 }
6361
6362 /****************************************************************************
6363  Deal with SMB_SET_POSIX_ACL.
6364 ****************************************************************************/
6365
6366 #if defined(HAVE_POSIX_ACLS)
6367 static NTSTATUS smb_set_posix_acl(connection_struct *conn,
6368                                 const char *pdata,
6369                                 int total_data,
6370                                 files_struct *fsp,
6371                                 const struct smb_filename *smb_fname)
6372 {
6373         uint16 posix_acl_version;
6374         uint16 num_file_acls;
6375         uint16 num_def_acls;
6376         bool valid_file_acls = True;
6377         bool valid_def_acls = True;
6378
6379         if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
6380                 return NT_STATUS_INVALID_PARAMETER;
6381         }
6382         posix_acl_version = SVAL(pdata,0);
6383         num_file_acls = SVAL(pdata,2);
6384         num_def_acls = SVAL(pdata,4);
6385
6386         if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
6387                 valid_file_acls = False;
6388                 num_file_acls = 0;
6389         }
6390
6391         if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
6392                 valid_def_acls = False;
6393                 num_def_acls = 0;
6394         }
6395
6396         if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
6397                 return NT_STATUS_INVALID_PARAMETER;
6398         }
6399
6400         if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
6401                         (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
6402                 return NT_STATUS_INVALID_PARAMETER;
6403         }
6404
6405         DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
6406                 smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp),
6407                 (unsigned int)num_file_acls,
6408                 (unsigned int)num_def_acls));
6409
6410         if (valid_file_acls && !set_unix_posix_acl(conn, fsp,
6411                 smb_fname->base_name, num_file_acls,
6412                 pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
6413                 return map_nt_error_from_unix(errno);
6414         }
6415
6416         if (valid_def_acls && !set_unix_posix_default_acl(conn,
6417                 smb_fname->base_name, &smb_fname->st, num_def_acls,
6418                 pdata + SMB_POSIX_ACL_HEADER_SIZE +
6419                 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
6420                 return map_nt_error_from_unix(errno);
6421         }
6422         return NT_STATUS_OK;
6423 }
6424 #endif
6425
6426 /****************************************************************************
6427  Deal with SMB_SET_POSIX_LOCK.
6428 ****************************************************************************/
6429
6430 static NTSTATUS smb_set_posix_lock(connection_struct *conn,
6431                                 struct smb_request *req,
6432                                 const char *pdata,
6433                                 int total_data,
6434                                 files_struct *fsp)
6435 {
6436         uint64_t count;
6437         uint64_t offset;
6438         uint64_t smblctx;
6439         bool blocking_lock = False;
6440         enum brl_type lock_type;
6441
6442         NTSTATUS status = NT_STATUS_OK;
6443
6444         if (fsp == NULL || fsp->fh->fd == -1) {
6445                 return NT_STATUS_INVALID_HANDLE;
6446         }
6447
6448         if (total_data != POSIX_LOCK_DATA_SIZE) {
6449                 return NT_STATUS_INVALID_PARAMETER;
6450         }
6451
6452         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
6453                 case POSIX_LOCK_TYPE_READ:
6454                         lock_type = READ_LOCK;
6455                         break;
6456                 case POSIX_LOCK_TYPE_WRITE:
6457                         /* Return the right POSIX-mappable error code for files opened read-only. */
6458                         if (!fsp->can_write) {
6459                                 return NT_STATUS_INVALID_HANDLE;
6460                         }
6461                         lock_type = WRITE_LOCK;
6462                         break;
6463                 case POSIX_LOCK_TYPE_UNLOCK:
6464                         lock_type = UNLOCK_LOCK;
6465                         break;
6466                 default:
6467                         return NT_STATUS_INVALID_PARAMETER;
6468         }
6469
6470         if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_NOWAIT) {
6471                 blocking_lock = False;
6472         } else if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_WAIT) {
6473                 blocking_lock = True;
6474         } else {
6475                 return NT_STATUS_INVALID_PARAMETER;
6476         }
6477
6478         if (!lp_blocking_locks(SNUM(conn))) { 
6479                 blocking_lock = False;
6480         }
6481
6482         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
6483 #if defined(HAVE_LONGLONG)
6484         offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
6485                         ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
6486         count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
6487                         ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
6488 #else /* HAVE_LONGLONG */
6489         offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET);
6490         count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
6491 #endif /* HAVE_LONGLONG */
6492
6493         DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
6494                         "smblctx = %llu, count = %.0f, offset = %.0f\n",
6495                 fsp_str_dbg(fsp),
6496                 (unsigned int)lock_type,
6497                 (unsigned long long)smblctx,
6498                 (double)count,
6499                 (double)offset ));
6500
6501         if (lock_type == UNLOCK_LOCK) {
6502                 status = do_unlock(req->sconn->msg_ctx,
6503                                 fsp,
6504                                 smblctx,
6505                                 count,
6506                                 offset,
6507                                 POSIX_LOCK);
6508         } else {
6509                 uint64_t block_smblctx;
6510
6511                 struct byte_range_lock *br_lck = do_lock(req->sconn->msg_ctx,
6512                                                         fsp,
6513                                                         smblctx,
6514                                                         count,
6515                                                         offset,
6516                                                         lock_type,
6517                                                         POSIX_LOCK,
6518                                                         blocking_lock,
6519                                                         &status,
6520                                                         &block_smblctx,
6521                                                         NULL);
6522
6523                 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
6524                         /*
6525                          * A blocking lock was requested. Package up
6526                          * this smb into a queued request and push it
6527                          * onto the blocking lock queue.
6528                          */
6529                         if(push_blocking_lock_request(br_lck,
6530                                                 req,
6531                                                 fsp,
6532                                                 -1, /* infinite timeout. */
6533                                                 0,
6534                                                 smblctx,
6535                                                 lock_type,
6536                                                 POSIX_LOCK,
6537                                                 offset,
6538                                                 count,
6539                                                 block_smblctx)) {
6540                                 TALLOC_FREE(br_lck);
6541                                 return status;
6542                         }
6543                 }
6544                 TALLOC_FREE(br_lck);
6545         }
6546
6547         return status;
6548 }
6549
6550 /****************************************************************************
6551  Deal with SMB_SET_FILE_BASIC_INFO.
6552 ****************************************************************************/
6553
6554 static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
6555                                         const char *pdata,
6556                                         int total_data,
6557                                         files_struct *fsp,
6558                                         const struct smb_filename *smb_fname)
6559 {
6560         /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
6561         struct smb_file_time ft;
6562         uint32 dosmode = 0;
6563         NTSTATUS status = NT_STATUS_OK;
6564
6565         ZERO_STRUCT(ft);
6566
6567         if (total_data < 36) {
6568                 return NT_STATUS_INVALID_PARAMETER;
6569         }
6570
6571         status = check_access(conn, fsp, smb_fname, FILE_WRITE_ATTRIBUTES);
6572         if (!NT_STATUS_IS_OK(status)) {
6573                 return status;
6574         }
6575
6576         /* Set the attributes */
6577         dosmode = IVAL(pdata,32);
6578         status = smb_set_file_dosmode(conn, smb_fname, dosmode);
6579         if (!NT_STATUS_IS_OK(status)) {
6580                 return status;
6581         }
6582
6583         /* create time */
6584         ft.create_time = interpret_long_date(pdata);
6585
6586         /* access time */
6587         ft.atime = interpret_long_date(pdata+8);
6588
6589         /* write time. */
6590         ft.mtime = interpret_long_date(pdata+16);
6591
6592         /* change time. */
6593         ft.ctime = interpret_long_date(pdata+24);
6594
6595         DEBUG(10, ("smb_set_file_basic_info: file %s\n",
6596                    smb_fname_str_dbg(smb_fname)));
6597
6598         return smb_set_file_time(conn, fsp, smb_fname, &ft,
6599                                  true);
6600 }
6601
6602 /****************************************************************************
6603  Deal with SMB_INFO_STANDARD.
6604 ****************************************************************************/
6605
6606 static NTSTATUS smb_set_info_standard(connection_struct *conn,
6607                                         const char *pdata,
6608                                         int total_data,
6609                                         files_struct *fsp,
6610                                         const struct smb_filename *smb_fname)
6611 {
6612         NTSTATUS status;
6613         struct smb_file_time ft;
6614
6615         ZERO_STRUCT(ft);
6616
6617         if (total_data < 12) {
6618                 return NT_STATUS_INVALID_PARAMETER;
6619         }
6620
6621         /* create time */
6622         ft.create_time = convert_time_t_to_timespec(srv_make_unix_date2(pdata));
6623         /* access time */
6624         ft.atime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+4));
6625         /* write time */
6626         ft.mtime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+8));
6627
6628         DEBUG(10,("smb_set_info_standard: file %s\n",
6629                 smb_fname_str_dbg(smb_fname)));
6630
6631         status = check_access(conn, fsp, smb_fname, FILE_WRITE_ATTRIBUTES);
6632         if (!NT_STATUS_IS_OK(status)) {
6633                 return status;
6634         }
6635
6636         return smb_set_file_time(conn,
6637                                 fsp,
6638                                 smb_fname,
6639                                 &ft,
6640                                 true);
6641 }
6642
6643 /****************************************************************************
6644  Deal with SMB_SET_FILE_ALLOCATION_INFO.
6645 ****************************************************************************/
6646
6647 static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
6648                                              struct smb_request *req,
6649                                         const char *pdata,
6650                                         int total_data,
6651                                         files_struct *fsp,
6652                                         struct smb_filename *smb_fname)
6653 {
6654         uint64_t allocation_size = 0;
6655         NTSTATUS status = NT_STATUS_OK;
6656         files_struct *new_fsp = NULL;
6657
6658         if (!VALID_STAT(smb_fname->st)) {
6659                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6660         }
6661
6662         if (total_data < 8) {
6663                 return NT_STATUS_INVALID_PARAMETER;
6664         }
6665
6666         allocation_size = (uint64_t)IVAL(pdata,0);
6667         allocation_size |= (((uint64_t)IVAL(pdata,4)) << 32);
6668         DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
6669                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
6670                   (double)allocation_size));
6671
6672         if (allocation_size) {
6673                 allocation_size = smb_roundup(conn, allocation_size);
6674         }
6675
6676         DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
6677                   "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname),
6678                   (double)allocation_size));
6679
6680         if (fsp && fsp->fh->fd != -1) {
6681                 /* Open file handle. */
6682                 if (!(fsp->access_mask & FILE_WRITE_DATA)) {
6683                         return NT_STATUS_ACCESS_DENIED;
6684                 }
6685
6686                 /* Only change if needed. */
6687                 if (allocation_size != get_file_size_stat(&smb_fname->st)) {
6688                         if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
6689                                 return map_nt_error_from_unix(errno);
6690                         }
6691                 }
6692                 /* But always update the time. */
6693                 /*
6694                  * This is equivalent to a write. Ensure it's seen immediately
6695                  * if there are no pending writes.
6696                  */
6697                 trigger_write_time_update_immediate(fsp);
6698                 return NT_STATUS_OK;
6699         }
6700
6701         /* Pathname or stat or directory file. */
6702         status = SMB_VFS_CREATE_FILE(
6703                 conn,                                   /* conn */
6704                 req,                                    /* req */
6705                 0,                                      /* root_dir_fid */
6706                 smb_fname,                              /* fname */
6707                 FILE_WRITE_DATA,                        /* access_mask */
6708                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
6709                     FILE_SHARE_DELETE),
6710                 FILE_OPEN,                              /* create_disposition*/
6711                 0,                                      /* create_options */
6712                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
6713                 FORCE_OPLOCK_BREAK_TO_NONE,             /* oplock_request */
6714                 0,                                      /* allocation_size */
6715                 0,                                      /* private_flags */
6716                 NULL,                                   /* sd */
6717                 NULL,                                   /* ea_list */
6718                 &new_fsp,                               /* result */
6719                 NULL);                                  /* pinfo */
6720
6721         if (!NT_STATUS_IS_OK(status)) {
6722                 /* NB. We check for open_was_deferred in the caller. */
6723                 return status;
6724         }
6725
6726         /* Only change if needed. */
6727         if (allocation_size != get_file_size_stat(&smb_fname->st)) {
6728                 if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
6729                         status = map_nt_error_from_unix(errno);
6730                         close_file(req, new_fsp, NORMAL_CLOSE);
6731                         return status;
6732                 }
6733         }
6734
6735         /* Changing the allocation size should set the last mod time. */
6736         /*
6737          * This is equivalent to a write. Ensure it's seen immediately
6738          * if there are no pending writes.
6739          */
6740         trigger_write_time_update_immediate(new_fsp);
6741
6742         close_file(req, new_fsp, NORMAL_CLOSE);
6743         return NT_STATUS_OK;
6744 }
6745
6746 /****************************************************************************
6747  Deal with SMB_SET_FILE_END_OF_FILE_INFO.
6748 ****************************************************************************/
6749
6750 static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
6751                                               struct smb_request *req,
6752                                         const char *pdata,
6753                                         int total_data,
6754                                         files_struct *fsp,
6755                                         const struct smb_filename *smb_fname,
6756                                         bool fail_after_createfile)
6757 {
6758         off_t size;
6759
6760         if (total_data < 8) {
6761                 return NT_STATUS_INVALID_PARAMETER;
6762         }
6763
6764         size = IVAL(pdata,0);
6765         size |= (((off_t)IVAL(pdata,4)) << 32);
6766         DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
6767                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
6768                   (double)size));
6769
6770         return smb_set_file_size(conn, req,
6771                                 fsp,
6772                                 smb_fname,
6773                                 &smb_fname->st,
6774                                 size,
6775                                 fail_after_createfile);
6776 }
6777
6778 /****************************************************************************
6779  Allow a UNIX info mknod.
6780 ****************************************************************************/
6781
6782 static NTSTATUS smb_unix_mknod(connection_struct *conn,
6783                                         const char *pdata,
6784                                         int total_data,
6785                                         const struct smb_filename *smb_fname)
6786 {
6787         uint32 file_type = IVAL(pdata,56);
6788 #if defined(HAVE_MAKEDEV)
6789         uint32 dev_major = IVAL(pdata,60);
6790         uint32 dev_minor = IVAL(pdata,68);
6791 #endif
6792         SMB_DEV_T dev = (SMB_DEV_T)0;
6793         uint32 raw_unixmode = IVAL(pdata,84);
6794         NTSTATUS status;
6795         mode_t unixmode;
6796
6797         if (total_data < 100) {
6798                 return NT_STATUS_INVALID_PARAMETER;
6799         }
6800
6801         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
6802                                       PERM_NEW_FILE, &unixmode);
6803         if (!NT_STATUS_IS_OK(status)) {
6804                 return status;
6805         }
6806
6807 #if defined(HAVE_MAKEDEV)
6808         dev = makedev(dev_major, dev_minor);
6809 #endif
6810
6811         switch (file_type) {
6812 #if defined(S_IFIFO)
6813                 case UNIX_TYPE_FIFO:
6814                         unixmode |= S_IFIFO;
6815                         break;
6816 #endif
6817 #if defined(S_IFSOCK)
6818                 case UNIX_TYPE_SOCKET:
6819                         unixmode |= S_IFSOCK;
6820                         break;
6821 #endif
6822 #if defined(S_IFCHR)
6823                 case UNIX_TYPE_CHARDEV:
6824                         unixmode |= S_IFCHR;
6825                         break;
6826 #endif
6827 #if defined(S_IFBLK)
6828                 case UNIX_TYPE_BLKDEV:
6829                         unixmode |= S_IFBLK;
6830                         break;
6831 #endif
6832                 default:
6833                         return NT_STATUS_INVALID_PARAMETER;
6834         }
6835
6836         DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
6837                   "%.0f mode 0%o for file %s\n", (double)dev,
6838                   (unsigned int)unixmode, smb_fname_str_dbg(smb_fname)));
6839
6840         /* Ok - do the mknod. */
6841         if (SMB_VFS_MKNOD(conn, smb_fname->base_name, unixmode, dev) != 0) {
6842                 return map_nt_error_from_unix(errno);
6843         }
6844
6845         /* If any of the other "set" calls fail we
6846          * don't want to end up with a half-constructed mknod.
6847          */
6848
6849         if (lp_inherit_perms(SNUM(conn))) {
6850                 char *parent;
6851                 if (!parent_dirname(talloc_tos(), smb_fname->base_name,
6852                                     &parent, NULL)) {
6853                         return NT_STATUS_NO_MEMORY;
6854                 }
6855                 inherit_access_posix_acl(conn, parent, smb_fname->base_name,
6856                                          unixmode);
6857                 TALLOC_FREE(parent);
6858         }
6859
6860         return NT_STATUS_OK;
6861 }
6862
6863 /****************************************************************************
6864  Deal with SMB_SET_FILE_UNIX_BASIC.
6865 ****************************************************************************/
6866
6867 static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
6868                                         struct smb_request *req,
6869                                         const char *pdata,
6870                                         int total_data,
6871                                         files_struct *fsp,
6872                                         const struct smb_filename *smb_fname)
6873 {
6874         struct smb_file_time ft;
6875         uint32 raw_unixmode;
6876         mode_t unixmode;
6877         off_t size = 0;
6878         uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
6879         gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
6880         NTSTATUS status = NT_STATUS_OK;
6881         bool delete_on_fail = False;
6882         enum perm_type ptype;
6883         files_struct *all_fsps = NULL;
6884         bool modify_mtime = true;
6885         struct file_id id;
6886         struct smb_filename *smb_fname_tmp = NULL;
6887         SMB_STRUCT_STAT sbuf;
6888
6889         ZERO_STRUCT(ft);
6890
6891         if (total_data < 100) {
6892                 return NT_STATUS_INVALID_PARAMETER;
6893         }
6894
6895         if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
6896            IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
6897                 size=IVAL(pdata,0); /* first 8 Bytes are size */
6898                 size |= (((off_t)IVAL(pdata,4)) << 32);
6899         }
6900
6901         ft.atime = interpret_long_date(pdata+24); /* access_time */
6902         ft.mtime = interpret_long_date(pdata+32); /* modification_time */
6903         set_owner = (uid_t)IVAL(pdata,40);
6904         set_grp = (gid_t)IVAL(pdata,48);
6905         raw_unixmode = IVAL(pdata,84);
6906
6907         if (VALID_STAT(smb_fname->st)) {
6908                 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
6909                         ptype = PERM_EXISTING_DIR;
6910                 } else {
6911                         ptype = PERM_EXISTING_FILE;
6912                 }
6913         } else {
6914                 ptype = PERM_NEW_FILE;
6915         }
6916
6917         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
6918                                       ptype, &unixmode);
6919         if (!NT_STATUS_IS_OK(status)) {
6920                 return status;
6921         }
6922
6923         DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
6924                   "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
6925                   smb_fname_str_dbg(smb_fname), (double)size,
6926                   (unsigned int)set_owner, (unsigned int)set_grp,
6927                   (int)raw_unixmode));
6928
6929         sbuf = smb_fname->st;
6930
6931         if (!VALID_STAT(sbuf)) {
6932                 /*
6933                  * The only valid use of this is to create character and block
6934                  * devices, and named pipes. This is deprecated (IMHO) and 
6935                  * a new info level should be used for mknod. JRA.
6936                  */
6937
6938                 status = smb_unix_mknod(conn,
6939                                         pdata,
6940                                         total_data,
6941                                         smb_fname);
6942                 if (!NT_STATUS_IS_OK(status)) {
6943                         return status;
6944                 }
6945
6946                 status = copy_smb_filename(talloc_tos(), smb_fname,
6947                                            &smb_fname_tmp);
6948                 if (!NT_STATUS_IS_OK(status)) {
6949                         return status;
6950                 }
6951
6952                 if (SMB_VFS_STAT(conn, smb_fname_tmp) != 0) {
6953                         status = map_nt_error_from_unix(errno);
6954                         TALLOC_FREE(smb_fname_tmp);
6955                         SMB_VFS_UNLINK(conn, smb_fname);
6956                         return status;
6957                 }
6958
6959                 sbuf = smb_fname_tmp->st;
6960                 smb_fname = smb_fname_tmp;
6961
6962                 /* Ensure we don't try and change anything else. */
6963                 raw_unixmode = SMB_MODE_NO_CHANGE;
6964                 size = get_file_size_stat(&sbuf);
6965                 ft.atime = sbuf.st_ex_atime;
6966                 ft.mtime = sbuf.st_ex_mtime;
6967                 /* 
6968                  * We continue here as we might want to change the 
6969                  * owner uid/gid.
6970                  */
6971                 delete_on_fail = True;
6972         }
6973
6974 #if 1
6975         /* Horrible backwards compatibility hack as an old server bug
6976          * allowed a CIFS client bug to remain unnoticed :-(. JRA.
6977          * */
6978
6979         if (!size) {
6980                 size = get_file_size_stat(&sbuf);
6981         }
6982 #endif
6983
6984         /*
6985          * Deal with the UNIX specific mode set.
6986          */
6987
6988         if (raw_unixmode != SMB_MODE_NO_CHANGE) {
6989                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
6990                           "setting mode 0%o for file %s\n",
6991                           (unsigned int)unixmode,
6992                           smb_fname_str_dbg(smb_fname)));
6993                 if (SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode) != 0) {
6994                         return map_nt_error_from_unix(errno);
6995                 }
6996         }
6997
6998         /*
6999          * Deal with the UNIX specific uid set.
7000          */
7001
7002         if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) &&
7003             (sbuf.st_ex_uid != set_owner)) {
7004                 int ret;
7005
7006                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7007                           "changing owner %u for path %s\n",
7008                           (unsigned int)set_owner,
7009                           smb_fname_str_dbg(smb_fname)));
7010
7011                 if (S_ISLNK(sbuf.st_ex_mode)) {
7012                         ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name,
7013                                              set_owner, (gid_t)-1);
7014                 } else {
7015                         ret = SMB_VFS_CHOWN(conn, smb_fname->base_name,
7016                                             set_owner, (gid_t)-1);
7017                 }
7018
7019                 if (ret != 0) {
7020                         status = map_nt_error_from_unix(errno);
7021                         if (delete_on_fail) {
7022                                 SMB_VFS_UNLINK(conn, smb_fname);
7023                         }
7024                         return status;
7025                 }
7026         }
7027
7028         /*
7029          * Deal with the UNIX specific gid set.
7030          */
7031
7032         if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) &&
7033             (sbuf.st_ex_gid != set_grp)) {
7034                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
7035                           "changing group %u for file %s\n",
7036                           (unsigned int)set_owner,
7037                           smb_fname_str_dbg(smb_fname)));
7038                 if (SMB_VFS_CHOWN(conn, smb_fname->base_name, (uid_t)-1,
7039                                   set_grp) != 0) {
7040                         status = map_nt_error_from_unix(errno);
7041                         if (delete_on_fail) {
7042                                 SMB_VFS_UNLINK(conn, smb_fname);
7043                         }
7044                         return status;
7045                 }
7046         }
7047
7048         /* Deal with any size changes. */
7049
7050         status = smb_set_file_size(conn, req,
7051                                    fsp,
7052                                    smb_fname,
7053                                    &sbuf,
7054                                    size,
7055                                    false);
7056         if (!NT_STATUS_IS_OK(status)) {
7057                 return status;
7058         }
7059
7060         /* Deal with any time changes. */
7061         if (null_timespec(ft.mtime) && null_timespec(ft.atime)) {
7062                 /* No change, don't cancel anything. */
7063                 return status;
7064         }
7065
7066         id = vfs_file_id_from_sbuf(conn, &sbuf);
7067         for(all_fsps = file_find_di_first(conn->sconn, id); all_fsps;
7068                         all_fsps = file_find_di_next(all_fsps)) {
7069                 /*
7070                  * We're setting the time explicitly for UNIX.
7071                  * Cancel any pending changes over all handles.
7072                  */
7073                 all_fsps->update_write_time_on_close = false;
7074                 TALLOC_FREE(all_fsps->update_write_time_event);
7075         }
7076
7077         /*
7078          * Override the "setting_write_time"
7079          * parameter here as it almost does what
7080          * we need. Just remember if we modified
7081          * mtime and send the notify ourselves.
7082          */
7083         if (null_timespec(ft.mtime)) {
7084                 modify_mtime = false;
7085         }
7086
7087         status = smb_set_file_time(conn,
7088                                 fsp,
7089                                 smb_fname,
7090                                 &ft,
7091                                 false);
7092         if (modify_mtime) {
7093                 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
7094                         FILE_NOTIFY_CHANGE_LAST_WRITE, smb_fname->base_name);
7095         }
7096         return status;
7097 }
7098
7099 /****************************************************************************
7100  Deal with SMB_SET_FILE_UNIX_INFO2.
7101 ****************************************************************************/
7102
7103 static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
7104                                         struct smb_request *req,
7105                                         const char *pdata,
7106                                         int total_data,
7107                                         files_struct *fsp,
7108                                         const struct smb_filename *smb_fname)
7109 {
7110         NTSTATUS status;
7111         uint32 smb_fflags;
7112         uint32 smb_fmask;
7113
7114         if (total_data < 116) {
7115                 return NT_STATUS_INVALID_PARAMETER;
7116         }
7117
7118         /* Start by setting all the fields that are common between UNIX_BASIC
7119          * and UNIX_INFO2.
7120          */
7121         status = smb_set_file_unix_basic(conn, req, pdata, total_data,
7122                                          fsp, smb_fname);
7123         if (!NT_STATUS_IS_OK(status)) {
7124                 return status;
7125         }
7126
7127         smb_fflags = IVAL(pdata, 108);
7128         smb_fmask = IVAL(pdata, 112);
7129
7130         /* NB: We should only attempt to alter the file flags if the client
7131          * sends a non-zero mask.
7132          */
7133         if (smb_fmask != 0) {
7134                 int stat_fflags = 0;
7135
7136                 if (!map_info2_flags_to_sbuf(&smb_fname->st, smb_fflags,
7137                                              smb_fmask, &stat_fflags)) {
7138                         /* Client asked to alter a flag we don't understand. */
7139                         return NT_STATUS_INVALID_PARAMETER;
7140                 }
7141
7142                 if (fsp && fsp->fh->fd != -1) {
7143                         /* XXX: we should be  using SMB_VFS_FCHFLAGS here. */
7144                         return NT_STATUS_NOT_SUPPORTED;
7145                 } else {
7146                         if (SMB_VFS_CHFLAGS(conn, smb_fname->base_name,
7147                                             stat_fflags) != 0) {
7148                                 return map_nt_error_from_unix(errno);
7149                         }
7150                 }
7151         }
7152
7153         /* XXX: need to add support for changing the create_time here. You
7154          * can do this for paths on Darwin with setattrlist(2). The right way
7155          * to hook this up is probably by extending the VFS utimes interface.
7156          */
7157
7158         return NT_STATUS_OK;
7159 }
7160
7161 /****************************************************************************
7162  Create a directory with POSIX semantics.
7163 ****************************************************************************/
7164
7165 static NTSTATUS smb_posix_mkdir(connection_struct *conn,
7166                                 struct smb_request *req,
7167                                 char **ppdata,
7168                                 int total_data,
7169                                 struct smb_filename *smb_fname,
7170                                 int *pdata_return_size)
7171 {
7172         NTSTATUS status = NT_STATUS_OK;
7173         uint32 raw_unixmode = 0;
7174         uint32 mod_unixmode = 0;
7175         mode_t unixmode = (mode_t)0;
7176         files_struct *fsp = NULL;
7177         uint16 info_level_return = 0;
7178         int info;
7179         char *pdata = *ppdata;
7180
7181         if (total_data < 18) {
7182                 return NT_STATUS_INVALID_PARAMETER;
7183         }
7184
7185         raw_unixmode = IVAL(pdata,8);
7186         /* Next 4 bytes are not yet defined. */
7187
7188         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
7189                                       PERM_NEW_DIR, &unixmode);
7190         if (!NT_STATUS_IS_OK(status)) {
7191                 return status;
7192         }
7193
7194         mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
7195
7196         DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
7197                   smb_fname_str_dbg(smb_fname), (unsigned int)unixmode));
7198
7199         status = SMB_VFS_CREATE_FILE(
7200                 conn,                                   /* conn */
7201                 req,                                    /* req */
7202                 0,                                      /* root_dir_fid */
7203                 smb_fname,                              /* fname */
7204                 FILE_READ_ATTRIBUTES,                   /* access_mask */
7205                 FILE_SHARE_NONE,                        /* share_access */
7206                 FILE_CREATE,                            /* create_disposition*/
7207                 FILE_DIRECTORY_FILE,                    /* create_options */
7208                 mod_unixmode,                           /* file_attributes */
7209                 0,                                      /* oplock_request */
7210                 0,                                      /* allocation_size */
7211                 0,                                      /* private_flags */
7212                 NULL,                                   /* sd */
7213                 NULL,                                   /* ea_list */
7214                 &fsp,                                   /* result */
7215                 &info);                                 /* pinfo */
7216
7217         if (NT_STATUS_IS_OK(status)) {
7218                 close_file(req, fsp, NORMAL_CLOSE);
7219         }
7220
7221         info_level_return = SVAL(pdata,16);
7222  
7223         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
7224                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
7225         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
7226                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
7227         } else {
7228                 *pdata_return_size = 12;
7229         }
7230
7231         /* Realloc the data size */
7232         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
7233         if (*ppdata == NULL) {
7234                 *pdata_return_size = 0;
7235                 return NT_STATUS_NO_MEMORY;
7236         }
7237         pdata = *ppdata;
7238
7239         SSVAL(pdata,0,NO_OPLOCK_RETURN);
7240         SSVAL(pdata,2,0); /* No fnum. */
7241         SIVAL(pdata,4,info); /* Was directory created. */
7242
7243         switch (info_level_return) {
7244                 case SMB_QUERY_FILE_UNIX_BASIC:
7245                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
7246                         SSVAL(pdata,10,0); /* Padding. */
7247                         store_file_unix_basic(conn, pdata + 12, fsp,
7248                                               &smb_fname->st);
7249                         break;
7250                 case SMB_QUERY_FILE_UNIX_INFO2:
7251                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
7252                         SSVAL(pdata,10,0); /* Padding. */
7253                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
7254                                                     &smb_fname->st);
7255                         break;
7256                 default:
7257                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
7258                         SSVAL(pdata,10,0); /* Padding. */
7259                         break;
7260         }
7261
7262         return status;
7263 }
7264
7265 /****************************************************************************
7266  Open/Create a file with POSIX semantics.
7267 ****************************************************************************/
7268
7269 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
7270 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
7271
7272 static NTSTATUS smb_posix_open(connection_struct *conn,
7273                                struct smb_request *req,
7274                                 char **ppdata,
7275                                 int total_data,
7276                                 struct smb_filename *smb_fname,
7277                                 int *pdata_return_size)
7278 {
7279         bool extended_oplock_granted = False;
7280         char *pdata = *ppdata;
7281         uint32 flags = 0;
7282         uint32 wire_open_mode = 0;
7283         uint32 raw_unixmode = 0;
7284         uint32 mod_unixmode = 0;
7285         uint32 create_disp = 0;
7286         uint32 access_mask = 0;
7287         uint32 create_options = FILE_NON_DIRECTORY_FILE;
7288         NTSTATUS status = NT_STATUS_OK;
7289         mode_t unixmode = (mode_t)0;
7290         files_struct *fsp = NULL;
7291         int oplock_request = 0;
7292         int info = 0;
7293         uint16 info_level_return = 0;
7294
7295         if (total_data < 18) {
7296                 return NT_STATUS_INVALID_PARAMETER;
7297         }
7298
7299         flags = IVAL(pdata,0);
7300         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
7301         if (oplock_request) {
7302                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
7303         }
7304
7305         wire_open_mode = IVAL(pdata,4);
7306
7307         if (wire_open_mode == (SMB_O_CREAT|SMB_O_DIRECTORY)) {
7308                 return smb_posix_mkdir(conn, req,
7309                                         ppdata,
7310                                         total_data,
7311                                         smb_fname,
7312                                         pdata_return_size);
7313         }
7314
7315         switch (wire_open_mode & SMB_ACCMODE) {
7316                 case SMB_O_RDONLY:
7317                         access_mask = SMB_O_RDONLY_MAPPING;
7318                         break;
7319                 case SMB_O_WRONLY:
7320                         access_mask = SMB_O_WRONLY_MAPPING;
7321                         break;
7322                 case SMB_O_RDWR:
7323                         access_mask = (SMB_O_RDONLY_MAPPING|
7324                                         SMB_O_WRONLY_MAPPING);
7325                         break;
7326                 default:
7327                         DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
7328                                 (unsigned int)wire_open_mode ));
7329                         return NT_STATUS_INVALID_PARAMETER;
7330         }
7331
7332         wire_open_mode &= ~SMB_ACCMODE;
7333
7334         /* First take care of O_CREAT|O_EXCL interactions. */
7335         switch (wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) {
7336                 case (SMB_O_CREAT | SMB_O_EXCL):
7337                         /* File exists fail. File not exist create. */
7338                         create_disp = FILE_CREATE;
7339                         break;
7340                 case SMB_O_CREAT:
7341                         /* File exists open. File not exist create. */
7342                         create_disp = FILE_OPEN_IF;
7343                         break;
7344                 case 0:
7345                         /* File exists open. File not exist fail. */
7346                         create_disp = FILE_OPEN;
7347                         break;
7348                 case SMB_O_EXCL:
7349                         /* O_EXCL on its own without O_CREAT is undefined. */
7350                 default:
7351                         DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
7352                                 (unsigned int)wire_open_mode ));
7353                         return NT_STATUS_INVALID_PARAMETER;
7354         }
7355
7356         /* Next factor in the effects of O_TRUNC. */
7357         wire_open_mode &= ~(SMB_O_CREAT | SMB_O_EXCL);
7358
7359         if (wire_open_mode & SMB_O_TRUNC) {
7360                 switch (create_disp) {
7361                         case FILE_CREATE:
7362                                 /* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
7363                                 /* Leave create_disp alone as
7364                                    (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
7365                                 */
7366                                 /* File exists fail. File not exist create. */
7367                                 break;
7368                         case FILE_OPEN_IF:
7369                                 /* SMB_O_CREAT | SMB_O_TRUNC */
7370                                 /* File exists overwrite. File not exist create. */
7371                                 create_disp = FILE_OVERWRITE_IF;
7372                                 break;
7373                         case FILE_OPEN:
7374                                 /* SMB_O_TRUNC */
7375                                 /* File exists overwrite. File not exist fail. */
7376                                 create_disp = FILE_OVERWRITE;
7377                                 break;
7378                         default:
7379                                 /* Cannot get here. */
7380                                 smb_panic("smb_posix_open: logic error");
7381                                 return NT_STATUS_INVALID_PARAMETER;
7382                 }
7383         }
7384
7385         raw_unixmode = IVAL(pdata,8);
7386         /* Next 4 bytes are not yet defined. */
7387
7388         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
7389                                       (VALID_STAT(smb_fname->st) ?
7390                                           PERM_EXISTING_FILE : PERM_NEW_FILE),
7391                                       &unixmode);
7392
7393         if (!NT_STATUS_IS_OK(status)) {
7394                 return status;
7395         }
7396
7397         mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
7398
7399         if (wire_open_mode & SMB_O_SYNC) {
7400                 create_options |= FILE_WRITE_THROUGH;
7401         }
7402         if (wire_open_mode & SMB_O_APPEND) {
7403                 access_mask |= FILE_APPEND_DATA;
7404         }
7405         if (wire_open_mode & SMB_O_DIRECT) {
7406                 mod_unixmode |= FILE_FLAG_NO_BUFFERING;
7407         }
7408
7409         if ((wire_open_mode & SMB_O_DIRECTORY) ||
7410                         VALID_STAT_OF_DIR(smb_fname->st)) {
7411                 if (access_mask != SMB_O_RDONLY_MAPPING) {
7412                         return NT_STATUS_FILE_IS_A_DIRECTORY;
7413                 }
7414                 create_options &= ~FILE_NON_DIRECTORY_FILE;
7415                 create_options |= FILE_DIRECTORY_FILE;
7416         }
7417
7418         DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
7419                 smb_fname_str_dbg(smb_fname),
7420                 (unsigned int)wire_open_mode,
7421                 (unsigned int)unixmode ));
7422
7423         status = SMB_VFS_CREATE_FILE(
7424                 conn,                                   /* conn */
7425                 req,                                    /* req */
7426                 0,                                      /* root_dir_fid */
7427                 smb_fname,                              /* fname */
7428                 access_mask,                            /* access_mask */
7429                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
7430                     FILE_SHARE_DELETE),
7431                 create_disp,                            /* create_disposition*/
7432                 create_options,                         /* create_options */
7433                 mod_unixmode,                           /* file_attributes */
7434                 oplock_request,                         /* oplock_request */
7435                 0,                                      /* allocation_size */
7436                 0,                                      /* private_flags */
7437                 NULL,                                   /* sd */
7438                 NULL,                                   /* ea_list */
7439                 &fsp,                                   /* result */
7440                 &info);                                 /* pinfo */
7441
7442         if (!NT_STATUS_IS_OK(status)) {
7443                 return status;
7444         }
7445
7446         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
7447                 extended_oplock_granted = True;
7448         }
7449
7450         if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
7451                 extended_oplock_granted = True;
7452         }
7453
7454         info_level_return = SVAL(pdata,16);
7455  
7456         /* Allocate the correct return size. */
7457
7458         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
7459                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
7460         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
7461                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
7462         } else {
7463                 *pdata_return_size = 12;
7464         }
7465
7466         /* Realloc the data size */
7467         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
7468         if (*ppdata == NULL) {
7469                 close_file(req, fsp, ERROR_CLOSE);
7470                 *pdata_return_size = 0;
7471                 return NT_STATUS_NO_MEMORY;
7472         }
7473         pdata = *ppdata;
7474
7475         if (extended_oplock_granted) {
7476                 if (flags & REQUEST_BATCH_OPLOCK) {
7477                         SSVAL(pdata,0, BATCH_OPLOCK_RETURN);
7478                 } else {
7479                         SSVAL(pdata,0, EXCLUSIVE_OPLOCK_RETURN);
7480                 }
7481         } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
7482                 SSVAL(pdata,0, LEVEL_II_OPLOCK_RETURN);
7483         } else {
7484                 SSVAL(pdata,0,NO_OPLOCK_RETURN);
7485         }
7486
7487         SSVAL(pdata,2,fsp->fnum);
7488         SIVAL(pdata,4,info); /* Was file created etc. */
7489
7490         switch (info_level_return) {
7491                 case SMB_QUERY_FILE_UNIX_BASIC:
7492                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
7493                         SSVAL(pdata,10,0); /* padding. */
7494                         store_file_unix_basic(conn, pdata + 12, fsp,
7495                                               &smb_fname->st);
7496                         break;
7497                 case SMB_QUERY_FILE_UNIX_INFO2:
7498                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
7499                         SSVAL(pdata,10,0); /* padding. */
7500                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
7501                                                     &smb_fname->st);
7502                         break;
7503                 default:
7504                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
7505                         SSVAL(pdata,10,0); /* padding. */
7506                         break;
7507         }
7508         return NT_STATUS_OK;
7509 }
7510
7511 /****************************************************************************
7512  Delete a file with POSIX semantics.
7513 ****************************************************************************/
7514
7515 static NTSTATUS smb_posix_unlink(connection_struct *conn,
7516                                  struct smb_request *req,
7517                                 const char *pdata,
7518                                 int total_data,
7519                                 struct smb_filename *smb_fname)
7520 {
7521         NTSTATUS status = NT_STATUS_OK;
7522         files_struct *fsp = NULL;
7523         uint16 flags = 0;
7524         char del = 1;
7525         int info = 0;
7526         int create_options = 0;
7527         int i;
7528         struct share_mode_lock *lck = NULL;
7529
7530         if (total_data < 2) {
7531                 return NT_STATUS_INVALID_PARAMETER;
7532         }
7533
7534         flags = SVAL(pdata,0);
7535
7536         if (!VALID_STAT(smb_fname->st)) {
7537                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
7538         }
7539
7540         if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
7541                         !VALID_STAT_OF_DIR(smb_fname->st)) {
7542                 return NT_STATUS_NOT_A_DIRECTORY;
7543         }
7544
7545         DEBUG(10,("smb_posix_unlink: %s %s\n",
7546                 (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
7547                 smb_fname_str_dbg(smb_fname)));
7548
7549         if (VALID_STAT_OF_DIR(smb_fname->st)) {
7550                 create_options |= FILE_DIRECTORY_FILE;
7551         }
7552
7553         status = SMB_VFS_CREATE_FILE(
7554                 conn,                                   /* conn */
7555                 req,                                    /* req */
7556                 0,                                      /* root_dir_fid */
7557                 smb_fname,                              /* fname */
7558                 DELETE_ACCESS,                          /* access_mask */
7559                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
7560                     FILE_SHARE_DELETE),
7561                 FILE_OPEN,                              /* create_disposition*/
7562                 create_options,                         /* create_options */
7563                 FILE_FLAG_POSIX_SEMANTICS|0777,         /* file_attributes */
7564                 0,                                      /* oplock_request */
7565                 0,                                      /* allocation_size */
7566                 0,                                      /* private_flags */
7567                 NULL,                                   /* sd */
7568                 NULL,                                   /* ea_list */
7569                 &fsp,                                   /* result */
7570                 &info);                                 /* pinfo */
7571
7572         if (!NT_STATUS_IS_OK(status)) {
7573                 return status;
7574         }
7575
7576         /*
7577          * Don't lie to client. If we can't really delete due to
7578          * non-POSIX opens return SHARING_VIOLATION.
7579          */
7580
7581         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
7582         if (lck == NULL) {
7583                 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
7584                           "lock for file %s\n", fsp_str_dbg(fsp)));
7585                 close_file(req, fsp, NORMAL_CLOSE);
7586                 return NT_STATUS_INVALID_PARAMETER;
7587         }
7588
7589         /*
7590          * See if others still have the file open. If this is the case, then
7591          * don't delete. If all opens are POSIX delete we can set the delete
7592          * on close disposition.
7593          */
7594         for (i=0; i<lck->data->num_share_modes; i++) {
7595                 struct share_mode_entry *e = &lck->data->share_modes[i];
7596                 if (is_valid_share_mode_entry(e)) {
7597                         if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
7598                                 continue;
7599                         }
7600                         if (share_mode_stale_pid(lck->data, i)) {
7601                                 continue;
7602                         }
7603                         /* Fail with sharing violation. */
7604                         close_file(req, fsp, NORMAL_CLOSE);
7605                         TALLOC_FREE(lck);
7606                         return NT_STATUS_SHARING_VIOLATION;
7607                 }
7608         }
7609
7610         /*
7611          * Set the delete on close.
7612          */
7613         status = smb_set_file_disposition_info(conn,
7614                                                 &del,
7615                                                 1,
7616                                                 fsp,
7617                                                 smb_fname);
7618
7619         if (!NT_STATUS_IS_OK(status)) {
7620                 close_file(req, fsp, NORMAL_CLOSE);
7621                 TALLOC_FREE(lck);
7622                 return status;
7623         }
7624         TALLOC_FREE(lck);
7625         return close_file(req, fsp, NORMAL_CLOSE);
7626 }
7627
7628 NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
7629                                 struct smb_request *req,
7630                                 TALLOC_CTX *mem_ctx,
7631                                 uint16_t info_level,
7632                                 files_struct *fsp,
7633                                 struct smb_filename *smb_fname,
7634                                 char **ppdata, int total_data,
7635                                 int *ret_data_size)
7636 {
7637         char *pdata = *ppdata;
7638         NTSTATUS status = NT_STATUS_OK;
7639         int data_return_size = 0;
7640
7641         *ret_data_size = 0;
7642
7643         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
7644                 return NT_STATUS_INVALID_LEVEL;
7645         }
7646
7647         if (!CAN_WRITE(conn)) {
7648                 /* Allow POSIX opens. The open path will deny
7649                  * any non-readonly opens. */
7650                 if (info_level != SMB_POSIX_PATH_OPEN) {
7651                         return NT_STATUS_DOS(ERRSRV, ERRaccess);
7652                 }
7653         }
7654
7655         DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d "
7656                  "totdata=%d\n", smb_fname_str_dbg(smb_fname),
7657                  fsp ? fsp->fnum : -1, info_level, total_data));
7658
7659         switch (info_level) {
7660
7661                 case SMB_INFO_STANDARD:
7662                 {
7663                         status = smb_set_info_standard(conn,
7664                                         pdata,
7665                                         total_data,
7666                                         fsp,
7667                                         smb_fname);
7668                         break;
7669                 }
7670
7671                 case SMB_INFO_SET_EA:
7672                 {
7673                         status = smb_info_set_ea(conn,
7674                                                 pdata,
7675                                                 total_data,
7676                                                 fsp,
7677                                                 smb_fname);
7678                         break;
7679                 }
7680
7681                 case SMB_SET_FILE_BASIC_INFO:
7682                 case SMB_FILE_BASIC_INFORMATION:
7683                 {
7684                         status = smb_set_file_basic_info(conn,
7685                                                         pdata,
7686                                                         total_data,
7687                                                         fsp,
7688                                                         smb_fname);
7689                         break;
7690                 }
7691
7692                 case SMB_FILE_ALLOCATION_INFORMATION:
7693                 case SMB_SET_FILE_ALLOCATION_INFO:
7694                 {
7695                         status = smb_set_file_allocation_info(conn, req,
7696                                                                 pdata,
7697                                                                 total_data,
7698                                                                 fsp,
7699                                                                 smb_fname);
7700                         break;
7701                 }
7702
7703                 case SMB_FILE_END_OF_FILE_INFORMATION:
7704                 case SMB_SET_FILE_END_OF_FILE_INFO:
7705                 {
7706                         /*
7707                          * XP/Win7 both fail after the createfile with
7708                          * SMB_SET_FILE_END_OF_FILE_INFO but not
7709                          * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
7710                          * The level is known here, so pass it down
7711                          * appropriately.
7712                          */
7713                         bool should_fail =
7714                             (info_level == SMB_SET_FILE_END_OF_FILE_INFO);
7715
7716                         status = smb_set_file_end_of_file_info(conn, req,
7717                                                                 pdata,
7718                                                                 total_data,
7719                                                                 fsp,
7720                                                                 smb_fname,
7721                                                                 should_fail);
7722                         break;
7723                 }
7724
7725                 case SMB_FILE_DISPOSITION_INFORMATION:
7726                 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
7727                 {
7728 #if 0
7729                         /* JRA - We used to just ignore this on a path ? 
7730                          * Shouldn't this be invalid level on a pathname
7731                          * based call ?
7732                          */
7733                         if (tran_call != TRANSACT2_SETFILEINFO) {
7734                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
7735                         }
7736 #endif
7737                         status = smb_set_file_disposition_info(conn,
7738                                                 pdata,
7739                                                 total_data,
7740                                                 fsp,
7741                                                 smb_fname);
7742                         break;
7743                 }
7744
7745                 case SMB_FILE_POSITION_INFORMATION:
7746                 {
7747                         status = smb_file_position_information(conn,
7748                                                 pdata,
7749                                                 total_data,
7750                                                 fsp);
7751                         break;
7752                 }
7753
7754                 case SMB_FILE_FULL_EA_INFORMATION:
7755                 {
7756                         status = smb_set_file_full_ea_info(conn,
7757                                                 pdata,
7758                                                 total_data,
7759                                                 fsp);
7760                         break;
7761                 }
7762
7763                 /* From tridge Samba4 : 
7764                  * MODE_INFORMATION in setfileinfo (I have no
7765                  * idea what "mode information" on a file is - it takes a value of 0,
7766                  * 2, 4 or 6. What could it be?).
7767                  */
7768
7769                 case SMB_FILE_MODE_INFORMATION:
7770                 {
7771                         status = smb_file_mode_information(conn,
7772                                                 pdata,
7773                                                 total_data);
7774                         break;
7775                 }
7776
7777                 /*
7778                  * CIFS UNIX extensions.
7779                  */
7780
7781                 case SMB_SET_FILE_UNIX_BASIC:
7782                 {
7783                         status = smb_set_file_unix_basic(conn, req,
7784                                                         pdata,
7785                                                         total_data,
7786                                                         fsp,
7787                                                         smb_fname);
7788                         break;
7789                 }
7790
7791                 case SMB_SET_FILE_UNIX_INFO2:
7792                 {
7793                         status = smb_set_file_unix_info2(conn, req,
7794                                                         pdata,
7795                                                         total_data,
7796                                                         fsp,
7797                                                         smb_fname);
7798                         break;
7799                 }
7800
7801                 case SMB_SET_FILE_UNIX_LINK:
7802                 {
7803                         if (fsp) {
7804                                 /* We must have a pathname for this. */
7805                                 return NT_STATUS_INVALID_LEVEL;
7806                         }
7807                         status = smb_set_file_unix_link(conn, req, pdata,
7808                                                         total_data, smb_fname);
7809                         break;
7810                 }
7811
7812                 case SMB_SET_FILE_UNIX_HLINK:
7813                 {
7814                         if (fsp) {
7815                                 /* We must have a pathname for this. */
7816                                 return NT_STATUS_INVALID_LEVEL;
7817                         }
7818                         status = smb_set_file_unix_hlink(conn, req,
7819                                                          pdata, total_data,
7820                                                          smb_fname);
7821                         break;
7822                 }
7823
7824                 case SMB_FILE_RENAME_INFORMATION:
7825                 {
7826                         status = smb_file_rename_information(conn, req,
7827                                                              pdata, total_data,
7828                                                              fsp, smb_fname);
7829                         break;
7830                 }
7831
7832                 case SMB2_FILE_RENAME_INFORMATION_INTERNAL:
7833                 {
7834                         /* SMB2 rename information. */
7835                         status = smb2_file_rename_information(conn, req,
7836                                                              pdata, total_data,
7837                                                              fsp, smb_fname);
7838                         break;
7839                 }
7840
7841                 case SMB_FILE_LINK_INFORMATION:
7842                 {
7843                         status = smb_file_link_information(conn, req,
7844                                                         pdata, total_data,
7845                                                         fsp, smb_fname);
7846                         break;
7847                 }
7848
7849 #if defined(HAVE_POSIX_ACLS)
7850                 case SMB_SET_POSIX_ACL:
7851                 {
7852                         status = smb_set_posix_acl(conn,
7853                                                 pdata,
7854                                                 total_data,
7855                                                 fsp,
7856                                                 smb_fname);
7857                         break;
7858                 }
7859 #endif
7860
7861                 case SMB_SET_POSIX_LOCK:
7862                 {
7863                         if (!fsp) {
7864                                 return NT_STATUS_INVALID_LEVEL;
7865                         }
7866                         status = smb_set_posix_lock(conn, req,
7867                                                     pdata, total_data, fsp);
7868                         break;
7869                 }
7870
7871                 case SMB_POSIX_PATH_OPEN:
7872                 {
7873                         if (fsp) {
7874                                 /* We must have a pathname for this. */
7875                                 return NT_STATUS_INVALID_LEVEL;
7876                         }
7877
7878                         status = smb_posix_open(conn, req,
7879                                                 ppdata,
7880                                                 total_data,
7881                                                 smb_fname,
7882                                                 &data_return_size);
7883                         break;
7884                 }
7885
7886                 case SMB_POSIX_PATH_UNLINK:
7887                 {
7888                         if (fsp) {
7889                                 /* We must have a pathname for this. */
7890                                 return NT_STATUS_INVALID_LEVEL;
7891                         }
7892
7893                         status = smb_posix_unlink(conn, req,
7894                                                 pdata,
7895                                                 total_data,
7896                                                 smb_fname);
7897                         break;
7898                 }
7899
7900                 default:
7901                         return NT_STATUS_INVALID_LEVEL;
7902         }
7903
7904         if (!NT_STATUS_IS_OK(status)) {
7905                 return status;
7906         }
7907
7908         *ret_data_size = data_return_size;
7909         return NT_STATUS_OK;
7910 }
7911
7912 /****************************************************************************
7913  Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
7914 ****************************************************************************/
7915
7916 static void call_trans2setfilepathinfo(connection_struct *conn,
7917                                        struct smb_request *req,
7918                                        unsigned int tran_call,
7919                                        char **pparams, int total_params,
7920                                        char **ppdata, int total_data,
7921                                        unsigned int max_data_bytes)
7922 {
7923         char *params = *pparams;
7924         char *pdata = *ppdata;
7925         uint16 info_level;
7926         struct smb_filename *smb_fname = NULL;
7927         files_struct *fsp = NULL;
7928         NTSTATUS status = NT_STATUS_OK;
7929         int data_return_size = 0;
7930
7931         if (!params) {
7932                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7933                 return;
7934         }
7935
7936         if (tran_call == TRANSACT2_SETFILEINFO) {
7937                 if (total_params < 4) {
7938                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7939                         return;
7940                 }
7941
7942                 fsp = file_fsp(req, SVAL(params,0));
7943                 /* Basic check for non-null fsp. */
7944                 if (!check_fsp_open(conn, req, fsp)) {
7945                         return;
7946                 }
7947                 info_level = SVAL(params,2);
7948
7949                 status = copy_smb_filename(talloc_tos(), fsp->fsp_name,
7950                                            &smb_fname);
7951                 if (!NT_STATUS_IS_OK(status)) {
7952                         reply_nterror(req, status);
7953                         return;
7954                 }
7955
7956                 if(fsp->fh->fd == -1) {
7957                         /*
7958                          * This is actually a SETFILEINFO on a directory
7959                          * handle (returned from an NT SMB). NT5.0 seems
7960                          * to do this call. JRA.
7961                          */
7962                         if (INFO_LEVEL_IS_UNIX(info_level)) {
7963                                 /* Always do lstat for UNIX calls. */
7964                                 if (SMB_VFS_LSTAT(conn, smb_fname)) {
7965                                         DEBUG(3,("call_trans2setfilepathinfo: "
7966                                                  "SMB_VFS_LSTAT of %s failed "
7967                                                  "(%s)\n",
7968                                                  smb_fname_str_dbg(smb_fname),
7969                                                  strerror(errno)));
7970                                         reply_nterror(req, map_nt_error_from_unix(errno));
7971                                         return;
7972                                 }
7973                         } else {
7974                                 if (SMB_VFS_STAT(conn, smb_fname) != 0) {
7975                                         DEBUG(3,("call_trans2setfilepathinfo: "
7976                                                  "fileinfo of %s failed (%s)\n",
7977                                                  smb_fname_str_dbg(smb_fname),
7978                                                  strerror(errno)));
7979                                         reply_nterror(req, map_nt_error_from_unix(errno));
7980                                         return;
7981                                 }
7982                         }
7983                 } else if (fsp->print_file) {
7984                         /*
7985                          * Doing a DELETE_ON_CLOSE should cancel a print job.
7986                          */
7987                         if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
7988                                 fsp->fh->private_options |= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE;
7989
7990                                 DEBUG(3,("call_trans2setfilepathinfo: "
7991                                          "Cancelling print job (%s)\n",
7992                                          fsp_str_dbg(fsp)));
7993
7994                                 SSVAL(params,0,0);
7995                                 send_trans2_replies(conn, req, params, 2,
7996                                                     *ppdata, 0,
7997                                                     max_data_bytes);
7998                                 return;
7999                         } else {
8000                                 reply_nterror(req,
8001                                         NT_STATUS_OBJECT_PATH_NOT_FOUND);
8002                                 return;
8003                         }
8004                 } else {
8005                         /*
8006                          * Original code - this is an open file.
8007                          */
8008                         if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
8009                                 DEBUG(3,("call_trans2setfilepathinfo: fstat "
8010                                          "of fnum %d failed (%s)\n", fsp->fnum,
8011                                          strerror(errno)));
8012                                 reply_nterror(req, map_nt_error_from_unix(errno));
8013                                 return;
8014                         }
8015                 }
8016         } else {
8017                 char *fname = NULL;
8018                 uint32_t ucf_flags = 0;
8019
8020                 /* set path info */
8021                 if (total_params < 7) {
8022                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8023                         return;
8024                 }
8025
8026                 info_level = SVAL(params,0);
8027                 srvstr_get_path(req, params, req->flags2, &fname, &params[6],
8028                                 total_params - 6, STR_TERMINATE,
8029                                 &status);
8030                 if (!NT_STATUS_IS_OK(status)) {
8031                         reply_nterror(req, status);
8032                         return;
8033                 }
8034
8035                 if (info_level == SMB_SET_FILE_UNIX_BASIC ||
8036                                 info_level == SMB_SET_FILE_UNIX_INFO2 ||
8037                                 info_level == SMB_FILE_RENAME_INFORMATION ||
8038                                 info_level == SMB_POSIX_PATH_UNLINK) {
8039                         ucf_flags |= UCF_UNIX_NAME_LOOKUP;
8040                 }
8041
8042                 status = filename_convert(req, conn,
8043                                          req->flags2 & FLAGS2_DFS_PATHNAMES,
8044                                          fname,
8045                                          ucf_flags,
8046                                          NULL,
8047                                          &smb_fname);
8048                 if (!NT_STATUS_IS_OK(status)) {
8049                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
8050                                 reply_botherror(req,
8051                                                 NT_STATUS_PATH_NOT_COVERED,
8052                                                 ERRSRV, ERRbadpath);
8053                                 return;
8054                         }
8055                         reply_nterror(req, status);
8056                         return;
8057                 }
8058
8059                 if (INFO_LEVEL_IS_UNIX(info_level)) {
8060                         /*
8061                          * For CIFS UNIX extensions the target name may not exist.
8062                          */
8063
8064                         /* Always do lstat for UNIX calls. */
8065                         SMB_VFS_LSTAT(conn, smb_fname);
8066
8067                 } else if (!VALID_STAT(smb_fname->st) &&
8068                            SMB_VFS_STAT(conn, smb_fname)) {
8069                         DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
8070                                  "%s failed (%s)\n",
8071                                  smb_fname_str_dbg(smb_fname),
8072                                  strerror(errno)));
8073                         reply_nterror(req, map_nt_error_from_unix(errno));
8074                         return;
8075                 }
8076         }
8077
8078         DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d "
8079                  "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
8080                  fsp ? fsp->fnum : -1, info_level,total_data));
8081
8082         /* Realloc the parameter size */
8083         *pparams = (char *)SMB_REALLOC(*pparams,2);
8084         if (*pparams == NULL) {
8085                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8086                 return;
8087         }
8088         params = *pparams;
8089
8090         SSVAL(params,0,0);
8091
8092         status = smbd_do_setfilepathinfo(conn, req, req,
8093                                          info_level,
8094                                          fsp,
8095                                          smb_fname,
8096                                          ppdata, total_data,
8097                                          &data_return_size);
8098         if (!NT_STATUS_IS_OK(status)) {
8099                 if (open_was_deferred(req->sconn, req->mid)) {
8100                         /* We have re-scheduled this call. */
8101                         return;
8102                 }
8103                 if (blocking_lock_was_deferred_smb1(req->sconn, req->mid)) {
8104                         /* We have re-scheduled this call. */
8105                         return;
8106                 }
8107                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
8108                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
8109                                         ERRSRV, ERRbadpath);
8110                         return;
8111                 }
8112                 if (info_level == SMB_POSIX_PATH_OPEN) {
8113                         reply_openerror(req, status);
8114                         return;
8115                 }
8116
8117                 reply_nterror(req, status);
8118                 return;
8119         }
8120
8121         send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
8122                             max_data_bytes);
8123
8124         return;
8125 }
8126
8127 /****************************************************************************
8128  Reply to a TRANS2_MKDIR (make directory with extended attributes).
8129 ****************************************************************************/
8130
8131 static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
8132                              char **pparams, int total_params,
8133                              char **ppdata, int total_data,
8134                              unsigned int max_data_bytes)
8135 {
8136         struct smb_filename *smb_dname = NULL;
8137         char *params = *pparams;
8138         char *pdata = *ppdata;
8139         char *directory = NULL;
8140         NTSTATUS status = NT_STATUS_OK;
8141         struct ea_list *ea_list = NULL;
8142         TALLOC_CTX *ctx = talloc_tos();
8143
8144         if (!CAN_WRITE(conn)) {
8145                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
8146                 return;
8147         }
8148
8149         if (total_params < 5) {
8150                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8151                 return;
8152         }
8153
8154         srvstr_get_path(ctx, params, req->flags2, &directory, &params[4],
8155                         total_params - 4, STR_TERMINATE,
8156                         &status);
8157         if (!NT_STATUS_IS_OK(status)) {
8158                 reply_nterror(req, status);
8159                 return;
8160         }
8161
8162         DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
8163
8164         status = filename_convert(ctx,
8165                                 conn,
8166                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
8167                                 directory,
8168                                 0,
8169                                 NULL,
8170                                 &smb_dname);
8171
8172         if (!NT_STATUS_IS_OK(status)) {
8173                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
8174                         reply_botherror(req,
8175                                 NT_STATUS_PATH_NOT_COVERED,
8176                                 ERRSRV, ERRbadpath);
8177                         return;
8178                 }
8179                 reply_nterror(req, status);
8180                 return;
8181         }
8182
8183         /*
8184          * OS/2 workplace shell seems to send SET_EA requests of "null"
8185          * length (4 bytes containing IVAL 4).
8186          * They seem to have no effect. Bug #3212. JRA.
8187          */
8188
8189         if (total_data && (total_data != 4)) {
8190                 /* Any data in this call is an EA list. */
8191                 if (total_data < 10) {
8192                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8193                         goto out;
8194                 }
8195
8196                 if (IVAL(pdata,0) > total_data) {
8197                         DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
8198                                 IVAL(pdata,0), (unsigned int)total_data));
8199                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8200                         goto out;
8201                 }
8202
8203                 ea_list = read_ea_list(talloc_tos(), pdata + 4,
8204                                        total_data - 4);
8205                 if (!ea_list) {
8206                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8207                         goto out;
8208                 }
8209
8210                 if (!lp_ea_support(SNUM(conn))) {
8211                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
8212                         goto out;
8213                 }
8214         }
8215         /* If total_data == 4 Windows doesn't care what values
8216          * are placed in that field, it just ignores them.
8217          * The System i QNTC IBM SMB client puts bad values here,
8218          * so ignore them. */
8219
8220         status = create_directory(conn, req, smb_dname);
8221
8222         if (!NT_STATUS_IS_OK(status)) {
8223                 reply_nterror(req, status);
8224                 goto out;
8225         }
8226
8227         /* Try and set any given EA. */
8228         if (ea_list) {
8229                 status = set_ea(conn, NULL, smb_dname, ea_list);
8230                 if (!NT_STATUS_IS_OK(status)) {
8231                         reply_nterror(req, status);
8232                         goto out;
8233                 }
8234         }
8235
8236         /* Realloc the parameter and data sizes */
8237         *pparams = (char *)SMB_REALLOC(*pparams,2);
8238         if(*pparams == NULL) {
8239                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8240                 goto out;
8241         }
8242         params = *pparams;
8243
8244         SSVAL(params,0,0);
8245
8246         send_trans2_replies(conn, req, params, 2, *ppdata, 0, max_data_bytes);
8247
8248  out:
8249         TALLOC_FREE(smb_dname);
8250         return;
8251 }
8252
8253 /****************************************************************************
8254  Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
8255  We don't actually do this - we just send a null response.
8256 ****************************************************************************/
8257
8258 static void call_trans2findnotifyfirst(connection_struct *conn,
8259                                        struct smb_request *req,
8260                                        char **pparams, int total_params,
8261                                        char **ppdata, int total_data,
8262                                        unsigned int max_data_bytes)
8263 {
8264         char *params = *pparams;
8265         uint16 info_level;
8266
8267         if (total_params < 6) {
8268                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8269                 return;
8270         }
8271
8272         info_level = SVAL(params,4);
8273         DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
8274
8275         switch (info_level) {
8276                 case 1:
8277                 case 2:
8278                         break;
8279                 default:
8280                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
8281                         return;
8282         }
8283
8284         /* Realloc the parameter and data sizes */
8285         *pparams = (char *)SMB_REALLOC(*pparams,6);
8286         if (*pparams == NULL) {
8287                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8288                 return;
8289         }
8290         params = *pparams;
8291
8292         SSVAL(params,0,fnf_handle);
8293         SSVAL(params,2,0); /* No changes */
8294         SSVAL(params,4,0); /* No EA errors */
8295
8296         fnf_handle++;
8297
8298         if(fnf_handle == 0)
8299                 fnf_handle = 257;
8300
8301         send_trans2_replies(conn, req, params, 6, *ppdata, 0, max_data_bytes);
8302
8303         return;
8304 }
8305
8306 /****************************************************************************
8307  Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for 
8308  changes). Currently this does nothing.
8309 ****************************************************************************/
8310
8311 static void call_trans2findnotifynext(connection_struct *conn,
8312                                       struct smb_request *req,
8313                                       char **pparams, int total_params,
8314                                       char **ppdata, int total_data,
8315                                       unsigned int max_data_bytes)
8316 {
8317         char *params = *pparams;
8318
8319         DEBUG(3,("call_trans2findnotifynext\n"));
8320
8321         /* Realloc the parameter and data sizes */
8322         *pparams = (char *)SMB_REALLOC(*pparams,4);
8323         if (*pparams == NULL) {
8324                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8325                 return;
8326         }
8327         params = *pparams;
8328
8329         SSVAL(params,0,0); /* No changes */
8330         SSVAL(params,2,0); /* No EA errors */
8331
8332         send_trans2_replies(conn, req, params, 4, *ppdata, 0, max_data_bytes);
8333
8334         return;
8335 }
8336
8337 /****************************************************************************
8338  Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
8339 ****************************************************************************/
8340
8341 static void call_trans2getdfsreferral(connection_struct *conn,
8342                                       struct smb_request *req,
8343                                       char **pparams, int total_params,
8344                                       char **ppdata, int total_data,
8345                                       unsigned int max_data_bytes)
8346 {
8347         char *params = *pparams;
8348         char *pathname = NULL;
8349         int reply_size = 0;
8350         int max_referral_level;
8351         NTSTATUS status = NT_STATUS_OK;
8352         TALLOC_CTX *ctx = talloc_tos();
8353
8354         DEBUG(10,("call_trans2getdfsreferral\n"));
8355
8356         if (total_params < 3) {
8357                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8358                 return;
8359         }
8360
8361         max_referral_level = SVAL(params,0);
8362
8363         if(!lp_host_msdfs()) {
8364                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
8365                 return;
8366         }
8367
8368         srvstr_pull_talloc(ctx, params, req->flags2, &pathname, &params[2],
8369                     total_params - 2, STR_TERMINATE);
8370         if (!pathname) {
8371                 reply_nterror(req, NT_STATUS_NOT_FOUND);
8372                 return;
8373         }
8374         if((reply_size = setup_dfs_referral(conn, pathname, max_referral_level,
8375                                             ppdata,&status)) < 0) {
8376                 reply_nterror(req, status);
8377                 return;
8378         }
8379
8380         SSVAL((discard_const_p(uint8_t, req->inbuf)), smb_flg2,
8381               SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
8382         send_trans2_replies(conn, req,0,0,*ppdata,reply_size, max_data_bytes);
8383
8384         return;
8385 }
8386
8387 #define LMCAT_SPL       0x53
8388 #define LMFUNC_GETJOBID 0x60
8389
8390 /****************************************************************************
8391  Reply to a TRANS2_IOCTL - used for OS/2 printing.
8392 ****************************************************************************/
8393
8394 static void call_trans2ioctl(connection_struct *conn,
8395                              struct smb_request *req,
8396                              char **pparams, int total_params,
8397                              char **ppdata, int total_data,
8398                              unsigned int max_data_bytes)
8399 {
8400         char *pdata = *ppdata;
8401         files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0));
8402
8403         /* check for an invalid fid before proceeding */
8404
8405         if (!fsp) {
8406                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
8407                 return;
8408         }
8409
8410         if ((SVAL(req->vwv+16, 0) == LMCAT_SPL)
8411             && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
8412                 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
8413                 if (*ppdata == NULL) {
8414                         reply_nterror(req, NT_STATUS_NO_MEMORY);
8415                         return;
8416                 }
8417                 pdata = *ppdata;
8418
8419                 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
8420                         CAN ACCEPT THIS IN UNICODE. JRA. */
8421
8422                 /* Job number */
8423                 SSVAL(pdata, 0, print_spool_rap_jobid(fsp->print_file));
8424
8425                 srvstr_push(pdata, req->flags2, pdata + 2,
8426                             lp_netbios_name(), 15,
8427                             STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
8428                 srvstr_push(pdata, req->flags2, pdata+18,
8429                             lp_servicename(SNUM(conn)), 13,
8430                             STR_ASCII|STR_TERMINATE); /* Service name */
8431                 send_trans2_replies(conn, req, *pparams, 0, *ppdata, 32,
8432                                     max_data_bytes);
8433                 return;
8434         }
8435
8436         DEBUG(2,("Unknown TRANS2_IOCTL\n"));
8437         reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
8438 }
8439
8440 /****************************************************************************
8441  Reply to a SMBfindclose (stop trans2 directory search).
8442 ****************************************************************************/
8443
8444 void reply_findclose(struct smb_request *req)
8445 {
8446         int dptr_num;
8447         struct smbd_server_connection *sconn = req->sconn;
8448
8449         START_PROFILE(SMBfindclose);
8450
8451         if (req->wct < 1) {
8452                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8453                 END_PROFILE(SMBfindclose);
8454                 return;
8455         }
8456
8457         dptr_num = SVALS(req->vwv+0, 0);
8458
8459         DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
8460
8461         dptr_close(sconn, &dptr_num);
8462
8463         reply_outbuf(req, 0, 0);
8464
8465         DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
8466
8467         END_PROFILE(SMBfindclose);
8468         return;
8469 }
8470
8471 /****************************************************************************
8472  Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
8473 ****************************************************************************/
8474
8475 void reply_findnclose(struct smb_request *req)
8476 {
8477         int dptr_num;
8478
8479         START_PROFILE(SMBfindnclose);
8480
8481         if (req->wct < 1) {
8482                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8483                 END_PROFILE(SMBfindnclose);
8484                 return;
8485         }
8486
8487         dptr_num = SVAL(req->vwv+0, 0);
8488
8489         DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
8490
8491         /* We never give out valid handles for a 
8492            findnotifyfirst - so any dptr_num is ok here. 
8493            Just ignore it. */
8494
8495         reply_outbuf(req, 0, 0);
8496
8497         DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
8498
8499         END_PROFILE(SMBfindnclose);
8500         return;
8501 }
8502
8503 static void handle_trans2(connection_struct *conn, struct smb_request *req,
8504                           struct trans_state *state)
8505 {
8506         if (get_Protocol() >= PROTOCOL_NT1) {
8507                 req->flags2 |= 0x40; /* IS_LONG_NAME */
8508                 SSVAL((discard_const_p(uint8_t, req->inbuf)),smb_flg2,req->flags2);
8509         }
8510
8511         if (conn->encrypt_level == Required && !req->encrypted) {
8512                 if (state->call != TRANSACT2_QFSINFO &&
8513                                 state->call != TRANSACT2_SETFSINFO) {
8514                         DEBUG(0,("handle_trans2: encryption required "
8515                                 "with call 0x%x\n",
8516                                 (unsigned int)state->call));
8517                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
8518                         return;
8519                 }
8520         }
8521
8522         SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
8523
8524         /* Now we must call the relevant TRANS2 function */
8525         switch(state->call)  {
8526         case TRANSACT2_OPEN:
8527         {
8528                 START_PROFILE(Trans2_open);
8529                 call_trans2open(conn, req,
8530                                 &state->param, state->total_param,
8531                                 &state->data, state->total_data,
8532                                 state->max_data_return);
8533                 END_PROFILE(Trans2_open);
8534                 break;
8535         }
8536
8537         case TRANSACT2_FINDFIRST:
8538         {
8539                 START_PROFILE(Trans2_findfirst);
8540                 call_trans2findfirst(conn, req,
8541                                      &state->param, state->total_param,
8542                                      &state->data, state->total_data,
8543                                      state->max_data_return);
8544                 END_PROFILE(Trans2_findfirst);
8545                 break;
8546         }
8547
8548         case TRANSACT2_FINDNEXT:
8549         {
8550                 START_PROFILE(Trans2_findnext);
8551                 call_trans2findnext(conn, req,
8552                                     &state->param, state->total_param,
8553                                     &state->data, state->total_data,
8554                                     state->max_data_return);
8555                 END_PROFILE(Trans2_findnext);
8556                 break;
8557         }
8558
8559         case TRANSACT2_QFSINFO:
8560         {
8561                 START_PROFILE(Trans2_qfsinfo);
8562                 call_trans2qfsinfo(conn, req,
8563                                    &state->param, state->total_param,
8564                                    &state->data, state->total_data,
8565                                    state->max_data_return);
8566                 END_PROFILE(Trans2_qfsinfo);
8567             break;
8568         }
8569
8570         case TRANSACT2_SETFSINFO:
8571         {
8572                 START_PROFILE(Trans2_setfsinfo);
8573                 call_trans2setfsinfo(conn, req,
8574                                      &state->param, state->total_param,
8575                                      &state->data, state->total_data,
8576                                      state->max_data_return);
8577                 END_PROFILE(Trans2_setfsinfo);
8578                 break;
8579         }
8580
8581         case TRANSACT2_QPATHINFO:
8582         case TRANSACT2_QFILEINFO:
8583         {
8584                 START_PROFILE(Trans2_qpathinfo);
8585                 call_trans2qfilepathinfo(conn, req, state->call,
8586                                          &state->param, state->total_param,
8587                                          &state->data, state->total_data,
8588                                          state->max_data_return);
8589                 END_PROFILE(Trans2_qpathinfo);
8590                 break;
8591         }
8592
8593         case TRANSACT2_SETPATHINFO:
8594         case TRANSACT2_SETFILEINFO:
8595         {
8596                 START_PROFILE(Trans2_setpathinfo);
8597                 call_trans2setfilepathinfo(conn, req, state->call,
8598                                            &state->param, state->total_param,
8599                                            &state->data, state->total_data,
8600                                            state->max_data_return);
8601                 END_PROFILE(Trans2_setpathinfo);
8602                 break;
8603         }
8604
8605         case TRANSACT2_FINDNOTIFYFIRST:
8606         {
8607                 START_PROFILE(Trans2_findnotifyfirst);
8608                 call_trans2findnotifyfirst(conn, req,
8609                                            &state->param, state->total_param,
8610                                            &state->data, state->total_data,
8611                                            state->max_data_return);
8612                 END_PROFILE(Trans2_findnotifyfirst);
8613                 break;
8614         }
8615
8616         case TRANSACT2_FINDNOTIFYNEXT:
8617         {
8618                 START_PROFILE(Trans2_findnotifynext);
8619                 call_trans2findnotifynext(conn, req,
8620                                           &state->param, state->total_param,
8621                                           &state->data, state->total_data,
8622                                           state->max_data_return);
8623                 END_PROFILE(Trans2_findnotifynext);
8624                 break;
8625         }
8626
8627         case TRANSACT2_MKDIR:
8628         {
8629                 START_PROFILE(Trans2_mkdir);
8630                 call_trans2mkdir(conn, req,
8631                                  &state->param, state->total_param,
8632                                  &state->data, state->total_data,
8633                                  state->max_data_return);
8634                 END_PROFILE(Trans2_mkdir);
8635                 break;
8636         }
8637
8638         case TRANSACT2_GET_DFS_REFERRAL:
8639         {
8640                 START_PROFILE(Trans2_get_dfs_referral);
8641                 call_trans2getdfsreferral(conn, req,
8642                                           &state->param, state->total_param,
8643                                           &state->data, state->total_data,
8644                                           state->max_data_return);
8645                 END_PROFILE(Trans2_get_dfs_referral);
8646                 break;
8647         }
8648
8649         case TRANSACT2_IOCTL:
8650         {
8651                 START_PROFILE(Trans2_ioctl);
8652                 call_trans2ioctl(conn, req,
8653                                  &state->param, state->total_param,
8654                                  &state->data, state->total_data,
8655                                  state->max_data_return);
8656                 END_PROFILE(Trans2_ioctl);
8657                 break;
8658         }
8659
8660         default:
8661                 /* Error in request */
8662                 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
8663                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
8664         }
8665 }
8666
8667 /****************************************************************************
8668  Reply to a SMBtrans2.
8669  ****************************************************************************/
8670
8671 void reply_trans2(struct smb_request *req)
8672 {
8673         connection_struct *conn = req->conn;
8674         unsigned int dsoff;
8675         unsigned int dscnt;
8676         unsigned int psoff;
8677         unsigned int pscnt;
8678         unsigned int tran_call;
8679         struct trans_state *state;
8680         NTSTATUS result;
8681
8682         START_PROFILE(SMBtrans2);
8683
8684         if (req->wct < 14) {
8685                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8686                 END_PROFILE(SMBtrans2);
8687                 return;
8688         }
8689
8690         dsoff = SVAL(req->vwv+12, 0);
8691         dscnt = SVAL(req->vwv+11, 0);
8692         psoff = SVAL(req->vwv+10, 0);
8693         pscnt = SVAL(req->vwv+9, 0);
8694         tran_call = SVAL(req->vwv+14, 0);
8695
8696         result = allow_new_trans(conn->pending_trans, req->mid);
8697         if (!NT_STATUS_IS_OK(result)) {
8698                 DEBUG(2, ("Got invalid trans2 request: %s\n",
8699                           nt_errstr(result)));
8700                 reply_nterror(req, result);
8701                 END_PROFILE(SMBtrans2);
8702                 return;
8703         }
8704
8705         if (IS_IPC(conn)) {
8706                 switch (tran_call) {
8707                 /* List the allowed trans2 calls on IPC$ */
8708                 case TRANSACT2_OPEN:
8709                 case TRANSACT2_GET_DFS_REFERRAL:
8710                 case TRANSACT2_QFILEINFO:
8711                 case TRANSACT2_QFSINFO:
8712                 case TRANSACT2_SETFSINFO:
8713                         break;
8714                 default:
8715                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
8716                         END_PROFILE(SMBtrans2);
8717                         return;
8718                 }
8719         }
8720
8721         if ((state = talloc(conn, struct trans_state)) == NULL) {
8722                 DEBUG(0, ("talloc failed\n"));
8723                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8724                 END_PROFILE(SMBtrans2);
8725                 return;
8726         }
8727
8728         state->cmd = SMBtrans2;
8729
8730         state->mid = req->mid;
8731         state->vuid = req->vuid;
8732         state->setup_count = SVAL(req->vwv+13, 0);
8733         state->setup = NULL;
8734         state->total_param = SVAL(req->vwv+0, 0);
8735         state->param = NULL;
8736         state->total_data =  SVAL(req->vwv+1, 0);
8737         state->data = NULL;
8738         state->max_param_return = SVAL(req->vwv+2, 0);
8739         state->max_data_return  = SVAL(req->vwv+3, 0);
8740         state->max_setup_return = SVAL(req->vwv+4, 0);
8741         state->close_on_completion = BITSETW(req->vwv+5, 0);
8742         state->one_way = BITSETW(req->vwv+5, 1);
8743
8744         state->call = tran_call;
8745
8746         /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
8747            is so as a sanity check */
8748         if (state->setup_count != 1) {
8749                 /*
8750                  * Need to have rc=0 for ioctl to get job id for OS/2.
8751                  *  Network printing will fail if function is not successful.
8752                  *  Similar function in reply.c will be used if protocol
8753                  *  is LANMAN1.0 instead of LM1.2X002.
8754                  *  Until DosPrintSetJobInfo with PRJINFO3 is supported,
8755                  *  outbuf doesn't have to be set(only job id is used).
8756                  */
8757                 if ( (state->setup_count == 4)
8758                      && (tran_call == TRANSACT2_IOCTL)
8759                      && (SVAL(req->vwv+16, 0) == LMCAT_SPL)
8760                      && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
8761                         DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
8762                 } else {
8763                         DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
8764                         DEBUG(2,("Transaction is %d\n",tran_call));
8765                         TALLOC_FREE(state);
8766                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8767                         END_PROFILE(SMBtrans2);
8768                         return;
8769                 }
8770         }
8771
8772         if ((dscnt > state->total_data) || (pscnt > state->total_param))
8773                 goto bad_param;
8774
8775         if (state->total_data) {
8776
8777                 if (trans_oob(state->total_data, 0, dscnt)
8778                     || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
8779                         goto bad_param;
8780                 }
8781
8782                 /* Can't use talloc here, the core routines do realloc on the
8783                  * params and data. */
8784                 state->data = (char *)SMB_MALLOC(state->total_data);
8785                 if (state->data == NULL) {
8786                         DEBUG(0,("reply_trans2: data malloc fail for %u "
8787                                  "bytes !\n", (unsigned int)state->total_data));
8788                         TALLOC_FREE(state);
8789                         reply_nterror(req, NT_STATUS_NO_MEMORY);
8790                         END_PROFILE(SMBtrans2);
8791                         return;
8792                 }
8793
8794                 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
8795         }
8796
8797         if (state->total_param) {
8798
8799                 if (trans_oob(state->total_param, 0, pscnt)
8800                     || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
8801                         goto bad_param;
8802                 }
8803
8804                 /* Can't use talloc here, the core routines do realloc on the
8805                  * params and data. */
8806                 state->param = (char *)SMB_MALLOC(state->total_param);
8807                 if (state->param == NULL) {
8808                         DEBUG(0,("reply_trans: param malloc fail for %u "
8809                                  "bytes !\n", (unsigned int)state->total_param));
8810                         SAFE_FREE(state->data);
8811                         TALLOC_FREE(state);
8812                         reply_nterror(req, NT_STATUS_NO_MEMORY);
8813                         END_PROFILE(SMBtrans2);
8814                         return;
8815                 } 
8816
8817                 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
8818         }
8819
8820         state->received_data  = dscnt;
8821         state->received_param = pscnt;
8822
8823         if ((state->received_param == state->total_param) &&
8824             (state->received_data == state->total_data)) {
8825
8826                 handle_trans2(conn, req, state);
8827
8828                 SAFE_FREE(state->data);
8829                 SAFE_FREE(state->param);
8830                 TALLOC_FREE(state);
8831                 END_PROFILE(SMBtrans2);
8832                 return;
8833         }
8834
8835         DLIST_ADD(conn->pending_trans, state);
8836
8837         /* We need to send an interim response then receive the rest
8838            of the parameter/data bytes */
8839         reply_outbuf(req, 0, 0);
8840         show_msg((char *)req->outbuf);
8841         END_PROFILE(SMBtrans2);
8842         return;
8843
8844   bad_param:
8845
8846         DEBUG(0,("reply_trans2: invalid trans parameters\n"));
8847         SAFE_FREE(state->data);
8848         SAFE_FREE(state->param);
8849         TALLOC_FREE(state);
8850         END_PROFILE(SMBtrans2);
8851         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8852 }
8853
8854
8855 /****************************************************************************
8856  Reply to a SMBtranss2
8857  ****************************************************************************/
8858
8859 void reply_transs2(struct smb_request *req)
8860 {
8861         connection_struct *conn = req->conn;
8862         unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
8863         struct trans_state *state;
8864
8865         START_PROFILE(SMBtranss2);
8866
8867         show_msg((const char *)req->inbuf);
8868
8869         if (req->wct < 8) {
8870                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8871                 END_PROFILE(SMBtranss2);
8872                 return;
8873         }
8874
8875         for (state = conn->pending_trans; state != NULL;
8876              state = state->next) {
8877                 if (state->mid == req->mid) {
8878                         break;
8879                 }
8880         }
8881
8882         if ((state == NULL) || (state->cmd != SMBtrans2)) {
8883                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8884                 END_PROFILE(SMBtranss2);
8885                 return;
8886         }
8887
8888         /* Revise state->total_param and state->total_data in case they have
8889            changed downwards */
8890
8891         if (SVAL(req->vwv+0, 0) < state->total_param)
8892                 state->total_param = SVAL(req->vwv+0, 0);
8893         if (SVAL(req->vwv+1, 0) < state->total_data)
8894                 state->total_data = SVAL(req->vwv+1, 0);
8895
8896         pcnt = SVAL(req->vwv+2, 0);
8897         poff = SVAL(req->vwv+3, 0);
8898         pdisp = SVAL(req->vwv+4, 0);
8899
8900         dcnt = SVAL(req->vwv+5, 0);
8901         doff = SVAL(req->vwv+6, 0);
8902         ddisp = SVAL(req->vwv+7, 0);
8903
8904         state->received_param += pcnt;
8905         state->received_data += dcnt;
8906
8907         if ((state->received_data > state->total_data) ||
8908             (state->received_param > state->total_param))
8909                 goto bad_param;
8910
8911         if (pcnt) {
8912                 if (trans_oob(state->total_param, pdisp, pcnt)
8913                     || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
8914                         goto bad_param;
8915                 }
8916                 memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
8917         }
8918
8919         if (dcnt) {
8920                 if (trans_oob(state->total_data, ddisp, dcnt)
8921                     || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
8922                         goto bad_param;
8923                 }
8924                 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
8925         }
8926
8927         if ((state->received_param < state->total_param) ||
8928             (state->received_data < state->total_data)) {
8929                 END_PROFILE(SMBtranss2);
8930                 return;
8931         }
8932
8933         handle_trans2(conn, req, state);
8934
8935         DLIST_REMOVE(conn->pending_trans, state);
8936         SAFE_FREE(state->data);
8937         SAFE_FREE(state->param);
8938         TALLOC_FREE(state);
8939
8940         END_PROFILE(SMBtranss2);
8941         return;
8942
8943   bad_param:
8944
8945         DEBUG(0,("reply_transs2: invalid trans parameters\n"));
8946         DLIST_REMOVE(conn->pending_trans, state);
8947         SAFE_FREE(state->data);
8948         SAFE_FREE(state->param);
8949         TALLOC_FREE(state);
8950         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8951         END_PROFILE(SMBtranss2);
8952         return;
8953 }