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