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