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