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