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