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