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