Fix bug 7399 - SMB2: QUERY_DIRECTORY is returning invalid values.
[samba.git] / source3 / smbd / trans2.c
1 /*
2    Unix SMB/CIFS implementation.
3    SMB transaction2 handling
4    Copyright (C) Jeremy Allison                 1994-2007
5    Copyright (C) Stefan (metze) Metzmacher      2003
6    Copyright (C) Volker Lendecke                2005-2007
7    Copyright (C) Steve French                   2005
8    Copyright (C) James Peach                    2006-2007
9
10    Extensively modified by Andrew Tridgell, 1995
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 3 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include "includes.h"
27 #include "version.h"
28 #include "smbd/globals.h"
29 #include "../libcli/auth/libcli_auth.h"
30 #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                                         NULL, 
3385                                         0);
3386                         }
3387
3388                         /* SID list byte count */
3389                         SIVAL(pdata, 32, sid_bytes);
3390
3391                         /* 4 bytes pad/reserved - must be zero */
3392                         SIVAL(pdata, 36, 0);
3393                         data_len = 40;
3394
3395                         /* GID list */
3396                         for (i = 0; i < conn->server_info->utok.ngroups; ++i) {
3397                                 SBIG_UINT(pdata, data_len,
3398                                           (uint64_t)conn->server_info->utok.groups[i]);
3399                                 data_len += 8;
3400                         }
3401
3402                         /* SID list */
3403                         for (i = 0;
3404                             i < conn->server_info->ptok->num_sids; ++i) {
3405                                 int sid_len = ndr_size_dom_sid(
3406                                         &conn->server_info->ptok->user_sids[i],
3407                                         NULL,
3408                                         0);
3409
3410                                 sid_linearize(pdata + data_len, sid_len,
3411                                     &conn->server_info->ptok->user_sids[i]);
3412                                 data_len += sid_len;
3413                         }
3414
3415                         break;
3416                 }
3417
3418                 case SMB_MAC_QUERY_FS_INFO:
3419                         /*
3420                          * Thursby MAC extension... ONLY on NTFS filesystems
3421                          * once we do streams then we don't need this
3422                          */
3423                         if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
3424                                 data_len = 88;
3425                                 SIVAL(pdata,84,0x100); /* Don't support mac... */
3426                                 break;
3427                         }
3428                         /* drop through */
3429                 default:
3430                         return NT_STATUS_INVALID_LEVEL;
3431         }
3432
3433         *ret_data_len = data_len;
3434         return NT_STATUS_OK;
3435 }
3436
3437 /****************************************************************************
3438  Reply to a TRANS2_QFSINFO (query filesystem info).
3439 ****************************************************************************/
3440
3441 static void call_trans2qfsinfo(connection_struct *conn,
3442                                struct smb_request *req,
3443                                char **pparams, int total_params,
3444                                char **ppdata, int total_data,
3445                                unsigned int max_data_bytes)
3446 {
3447         char *params = *pparams;
3448         uint16_t info_level;
3449         int data_len = 0;
3450         NTSTATUS status;
3451
3452         if (total_params < 2) {
3453                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3454                 return;
3455         }
3456
3457         info_level = SVAL(params,0);
3458
3459         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
3460                 if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
3461                         DEBUG(0,("call_trans2qfsinfo: encryption required "
3462                                 "and info level 0x%x sent.\n",
3463                                 (unsigned int)info_level));
3464                         exit_server_cleanly("encryption required "
3465                                 "on connection");
3466                         return;
3467                 }
3468         }
3469
3470         DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
3471
3472         status = smbd_do_qfsinfo(conn, req,
3473                                  info_level,
3474                                  req->flags2,
3475                                  max_data_bytes,
3476                                  ppdata, &data_len);
3477         if (!NT_STATUS_IS_OK(status)) {
3478                 reply_nterror(req, status);
3479                 return;
3480         }
3481
3482         send_trans2_replies(conn, req, params, 0, *ppdata, data_len,
3483                             max_data_bytes);
3484
3485         DEBUG( 4, ( "%s info_level = %d\n",
3486                     smb_fn_name(req->cmd), info_level) );
3487
3488         return;
3489 }
3490
3491 /****************************************************************************
3492  Reply to a TRANS2_SETFSINFO (set filesystem info).
3493 ****************************************************************************/
3494
3495 static void call_trans2setfsinfo(connection_struct *conn,
3496                                  struct smb_request *req,
3497                                  char **pparams, int total_params,
3498                                  char **ppdata, int total_data,
3499                                  unsigned int max_data_bytes)
3500 {
3501         char *pdata = *ppdata;
3502         char *params = *pparams;
3503         uint16 info_level;
3504
3505         DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn))));
3506
3507         /*  */
3508         if (total_params < 4) {
3509                 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
3510                         total_params));
3511                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3512                 return;
3513         }
3514
3515         info_level = SVAL(params,2);
3516
3517         if (IS_IPC(conn)) {
3518                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION &&
3519                                 info_level != SMB_SET_CIFS_UNIX_INFO) {
3520                         DEBUG(0,("call_trans2setfsinfo: not an allowed "
3521                                 "info level (0x%x) on IPC$.\n",
3522                                 (unsigned int)info_level));
3523                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
3524                         return;
3525                 }
3526         }
3527
3528         if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
3529                 if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
3530                         DEBUG(0,("call_trans2setfsinfo: encryption required "
3531                                 "and info level 0x%x sent.\n",
3532                                 (unsigned int)info_level));
3533                         exit_server_cleanly("encryption required "
3534                                 "on connection");
3535                         return;
3536                 }
3537         }
3538
3539         switch(info_level) {
3540                 case SMB_SET_CIFS_UNIX_INFO:
3541                         {
3542                                 uint16 client_unix_major;
3543                                 uint16 client_unix_minor;
3544                                 uint32 client_unix_cap_low;
3545                                 uint32 client_unix_cap_high;
3546
3547                                 if (!lp_unix_extensions()) {
3548                                         reply_nterror(req,
3549                                                       NT_STATUS_INVALID_LEVEL);
3550                                         return;
3551                                 }
3552
3553                                 /* There should be 12 bytes of capabilities set. */
3554                                 if (total_data < 8) {
3555                                         reply_nterror(
3556                                                 req,
3557                                                 NT_STATUS_INVALID_PARAMETER);
3558                                         return;
3559                                 }
3560                                 client_unix_major = SVAL(pdata,0);
3561                                 client_unix_minor = SVAL(pdata,2);
3562                                 client_unix_cap_low = IVAL(pdata,4);
3563                                 client_unix_cap_high = IVAL(pdata,8);
3564                                 /* Just print these values for now. */
3565                                 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
3566 cap_low = 0x%x, cap_high = 0x%x\n",
3567                                         (unsigned int)client_unix_major,
3568                                         (unsigned int)client_unix_minor,
3569                                         (unsigned int)client_unix_cap_low,
3570                                         (unsigned int)client_unix_cap_high ));
3571
3572                                 /* Here is where we must switch to posix pathname processing... */
3573                                 if (client_unix_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
3574                                         lp_set_posix_pathnames();
3575                                         mangle_change_to_posix();
3576                                 }
3577
3578                                 if ((client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
3579                                     !(client_unix_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
3580                                         /* Client that knows how to do posix locks,
3581                                          * but not posix open/mkdir operations. Set a
3582                                          * default type for read/write checks. */
3583
3584                                         lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
3585
3586                                 }
3587                                 break;
3588                         }
3589
3590                 case SMB_REQUEST_TRANSPORT_ENCRYPTION:
3591                         {
3592                                 NTSTATUS status;
3593                                 size_t param_len = 0;
3594                                 size_t data_len = total_data;
3595
3596                                 if (!lp_unix_extensions()) {
3597                                         reply_nterror(
3598                                                 req,
3599                                                 NT_STATUS_INVALID_LEVEL);
3600                                         return;
3601                                 }
3602
3603                                 if (lp_smb_encrypt(SNUM(conn)) == false) {
3604                                         reply_nterror(
3605                                                 req,
3606                                                 NT_STATUS_NOT_SUPPORTED);
3607                                         return;
3608                                 }
3609
3610                                 if (smbd_server_conn->smb1.echo_handler.trusted_fde) {
3611                                         DEBUG( 2,("call_trans2setfsinfo: "
3612                                                 "request transport encryption disabled"
3613                                                 "with 'fork echo handler = yes'\n"));
3614                                         reply_nterror(
3615                                                 req,
3616                                                 NT_STATUS_NOT_SUPPORTED);
3617                                         return;
3618                                 }
3619
3620                                 DEBUG( 4,("call_trans2setfsinfo: "
3621                                         "request transport encryption.\n"));
3622
3623                                 status = srv_request_encryption_setup(conn,
3624                                                                 (unsigned char **)ppdata,
3625                                                                 &data_len,
3626                                                                 (unsigned char **)pparams,
3627                                                                 &param_len);
3628
3629                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
3630                                                 !NT_STATUS_IS_OK(status)) {
3631                                         reply_nterror(req, status);
3632                                         return;
3633                                 }
3634
3635                                 send_trans2_replies(conn, req,
3636                                                 *pparams,
3637                                                 param_len,
3638                                                 *ppdata,
3639                                                 data_len,
3640                                                 max_data_bytes);
3641
3642                                 if (NT_STATUS_IS_OK(status)) {
3643                                         /* Server-side transport
3644                                          * encryption is now *on*. */
3645                                         status = srv_encryption_start(conn);
3646                                         if (!NT_STATUS_IS_OK(status)) {
3647                                                 exit_server_cleanly(
3648                                                         "Failure in setting "
3649                                                         "up encrypted transport");
3650                                         }
3651                                 }
3652                                 return;
3653                         }
3654
3655                 case SMB_FS_QUOTA_INFORMATION:
3656                         {
3657                                 files_struct *fsp = NULL;
3658                                 SMB_NTQUOTA_STRUCT quotas;
3659
3660                                 ZERO_STRUCT(quotas);
3661
3662                                 /* access check */
3663                                 if ((conn->server_info->utok.uid != sec_initial_uid())
3664                                     ||!CAN_WRITE(conn)) {
3665                                         DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
3666                                                  lp_servicename(SNUM(conn)),
3667                                                  conn->server_info->unix_name));
3668                                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
3669                                         return;
3670                                 }
3671
3672                                 /* note: normaly there're 48 bytes,
3673                                  * but we didn't use the last 6 bytes for now 
3674                                  * --metze 
3675                                  */
3676                                 fsp = file_fsp(req, SVAL(params,0));
3677
3678                                 if (!check_fsp_ntquota_handle(conn, req,
3679                                                               fsp)) {
3680                                         DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
3681                                         reply_nterror(
3682                                                 req, NT_STATUS_INVALID_HANDLE);
3683                                         return;
3684                                 }
3685
3686                                 if (total_data < 42) {
3687                                         DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
3688                                                 total_data));
3689                                         reply_nterror(
3690                                                 req,
3691                                                 NT_STATUS_INVALID_PARAMETER);
3692                                         return;
3693                                 }
3694
3695                                 /* unknown_1 24 NULL bytes in pdata*/
3696
3697                                 /* the soft quotas 8 bytes (uint64_t)*/
3698                                 quotas.softlim = (uint64_t)IVAL(pdata,24);
3699 #ifdef LARGE_SMB_OFF_T
3700                                 quotas.softlim |= (((uint64_t)IVAL(pdata,28)) << 32);
3701 #else /* LARGE_SMB_OFF_T */
3702                                 if ((IVAL(pdata,28) != 0)&&
3703                                         ((quotas.softlim != 0xFFFFFFFF)||
3704                                         (IVAL(pdata,28)!=0xFFFFFFFF))) {
3705                                         /* more than 32 bits? */
3706                                         reply_nterror(
3707                                                 req,
3708                                                 NT_STATUS_INVALID_PARAMETER);
3709                                         return;
3710                                 }
3711 #endif /* LARGE_SMB_OFF_T */
3712
3713                                 /* the hard quotas 8 bytes (uint64_t)*/
3714                                 quotas.hardlim = (uint64_t)IVAL(pdata,32);
3715 #ifdef LARGE_SMB_OFF_T
3716                                 quotas.hardlim |= (((uint64_t)IVAL(pdata,36)) << 32);
3717 #else /* LARGE_SMB_OFF_T */
3718                                 if ((IVAL(pdata,36) != 0)&&
3719                                         ((quotas.hardlim != 0xFFFFFFFF)||
3720                                         (IVAL(pdata,36)!=0xFFFFFFFF))) {
3721                                         /* more than 32 bits? */
3722                                         reply_nterror(
3723                                                 req,
3724                                                 NT_STATUS_INVALID_PARAMETER);
3725                                         return;
3726                                 }
3727 #endif /* LARGE_SMB_OFF_T */
3728
3729                                 /* quota_flags 2 bytes **/
3730                                 quotas.qflags = SVAL(pdata,40);
3731
3732                                 /* unknown_2 6 NULL bytes follow*/
3733
3734                                 /* now set the quotas */
3735                                 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
3736                                         DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
3737                                         reply_nterror(req, map_nt_error_from_unix(errno));
3738                                         return;
3739                                 }
3740
3741                                 break;
3742                         }
3743                 default:
3744                         DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
3745                                 info_level));
3746                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3747                         return;
3748                         break;
3749         }
3750
3751         /* 
3752          * sending this reply works fine, 
3753          * but I'm not sure it's the same 
3754          * like windows do...
3755          * --metze
3756          */
3757         reply_outbuf(req, 10, 0);
3758 }
3759
3760 #if defined(HAVE_POSIX_ACLS)
3761 /****************************************************************************
3762  Utility function to count the number of entries in a POSIX acl.
3763 ****************************************************************************/
3764
3765 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
3766 {
3767         unsigned int ace_count = 0;
3768         int entry_id = SMB_ACL_FIRST_ENTRY;
3769         SMB_ACL_ENTRY_T entry;
3770
3771         while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
3772                 /* get_next... */
3773                 if (entry_id == SMB_ACL_FIRST_ENTRY) {
3774                         entry_id = SMB_ACL_NEXT_ENTRY;
3775                 }
3776                 ace_count++;
3777         }
3778         return ace_count;
3779 }
3780
3781 /****************************************************************************
3782  Utility function to marshall a POSIX acl into wire format.
3783 ****************************************************************************/
3784
3785 static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
3786 {
3787         int entry_id = SMB_ACL_FIRST_ENTRY;
3788         SMB_ACL_ENTRY_T entry;
3789
3790         while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
3791                 SMB_ACL_TAG_T tagtype;
3792                 SMB_ACL_PERMSET_T permset;
3793                 unsigned char perms = 0;
3794                 unsigned int own_grp;
3795
3796                 /* get_next... */
3797                 if (entry_id == SMB_ACL_FIRST_ENTRY) {
3798                         entry_id = SMB_ACL_NEXT_ENTRY;
3799                 }
3800
3801                 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
3802                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
3803                         return False;
3804                 }
3805
3806                 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
3807                         DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
3808                         return False;
3809                 }
3810
3811                 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
3812                 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
3813                 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
3814
3815                 SCVAL(pdata,1,perms);
3816
3817                 switch (tagtype) {
3818                         case SMB_ACL_USER_OBJ:
3819                                 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
3820                                 own_grp = (unsigned int)pst->st_ex_uid;
3821                                 SIVAL(pdata,2,own_grp);
3822                                 SIVAL(pdata,6,0);
3823                                 break;
3824                         case SMB_ACL_USER:
3825                                 {
3826                                         uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
3827                                         if (!puid) {
3828                                                 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3829                                                 return False;
3830                                         }
3831                                         own_grp = (unsigned int)*puid;
3832                                         SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
3833                                         SCVAL(pdata,0,SMB_POSIX_ACL_USER);
3834                                         SIVAL(pdata,2,own_grp);
3835                                         SIVAL(pdata,6,0);
3836                                         break;
3837                                 }
3838                         case SMB_ACL_GROUP_OBJ:
3839                                 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
3840                                 own_grp = (unsigned int)pst->st_ex_gid;
3841                                 SIVAL(pdata,2,own_grp);
3842                                 SIVAL(pdata,6,0);
3843                                 break;
3844                         case SMB_ACL_GROUP:
3845                                 {
3846                                         gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
3847                                         if (!pgid) {
3848                                                 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
3849                                                 return False;
3850                                         }
3851                                         own_grp = (unsigned int)*pgid;
3852                                         SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
3853                                         SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
3854                                         SIVAL(pdata,2,own_grp);
3855                                         SIVAL(pdata,6,0);
3856                                         break;
3857                                 }
3858                         case SMB_ACL_MASK:
3859                                 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
3860                                 SIVAL(pdata,2,0xFFFFFFFF);
3861                                 SIVAL(pdata,6,0xFFFFFFFF);
3862                                 break;
3863                         case SMB_ACL_OTHER:
3864                                 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
3865                                 SIVAL(pdata,2,0xFFFFFFFF);
3866                                 SIVAL(pdata,6,0xFFFFFFFF);
3867                                 break;
3868                         default:
3869                                 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
3870                                 return False;
3871                 }
3872                 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
3873         }
3874
3875         return True;
3876 }
3877 #endif
3878
3879 /****************************************************************************
3880  Store the FILE_UNIX_BASIC info.
3881 ****************************************************************************/
3882
3883 static char *store_file_unix_basic(connection_struct *conn,
3884                                 char *pdata,
3885                                 files_struct *fsp,
3886                                 const SMB_STRUCT_STAT *psbuf)
3887 {
3888         DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
3889         DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_ex_mode));
3890
3891         SOFF_T(pdata,0,get_file_size_stat(psbuf));             /* File size 64 Bit */
3892         pdata += 8;
3893
3894         SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
3895         pdata += 8;
3896
3897         put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata, psbuf->st_ex_ctime);       /* Change Time 64 Bit */
3898         put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER ,pdata+8, psbuf->st_ex_atime);     /* Last access time 64 Bit */
3899         put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata+16, psbuf->st_ex_mtime);    /* Last modification time 64 Bit */
3900         pdata += 24;
3901
3902         SIVAL(pdata,0,psbuf->st_ex_uid);               /* user id for the owner */
3903         SIVAL(pdata,4,0);
3904         pdata += 8;
3905
3906         SIVAL(pdata,0,psbuf->st_ex_gid);               /* group id of owner */
3907         SIVAL(pdata,4,0);
3908         pdata += 8;
3909
3910         SIVAL(pdata,0,unix_filetype(psbuf->st_ex_mode));
3911         pdata += 4;
3912
3913         SIVAL(pdata,0,unix_dev_major(psbuf->st_ex_rdev));   /* Major device number if type is device */
3914         SIVAL(pdata,4,0);
3915         pdata += 8;
3916
3917         SIVAL(pdata,0,unix_dev_minor(psbuf->st_ex_rdev));   /* Minor device number if type is device */
3918         SIVAL(pdata,4,0);
3919         pdata += 8;
3920
3921         SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ex_ino);   /* inode number */
3922         pdata += 8;
3923
3924         SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode));     /* Standard UNIX file permissions */
3925         SIVAL(pdata,4,0);
3926         pdata += 8;
3927
3928         SIVAL(pdata,0,psbuf->st_ex_nlink);             /* number of hard links */
3929         SIVAL(pdata,4,0);
3930         pdata += 8;
3931
3932         return pdata;
3933 }
3934
3935 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
3936  * the chflags(2) (or equivalent) flags.
3937  *
3938  * XXX: this really should be behind the VFS interface. To do this, we would
3939  * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
3940  * Each VFS module could then implement its own mapping as appropriate for the
3941  * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
3942  */
3943 static const struct {unsigned stat_fflag; unsigned smb_fflag;}
3944         info2_flags_map[] =
3945 {
3946 #ifdef UF_NODUMP
3947     { UF_NODUMP, EXT_DO_NOT_BACKUP },
3948 #endif
3949
3950 #ifdef UF_IMMUTABLE
3951     { UF_IMMUTABLE, EXT_IMMUTABLE },
3952 #endif
3953
3954 #ifdef UF_APPEND
3955     { UF_APPEND, EXT_OPEN_APPEND_ONLY },
3956 #endif
3957
3958 #ifdef UF_HIDDEN
3959     { UF_HIDDEN, EXT_HIDDEN },
3960 #endif
3961
3962     /* Do not remove. We need to guarantee that this array has at least one
3963      * entry to build on HP-UX.
3964      */
3965     { 0, 0 }
3966
3967 };
3968
3969 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf,
3970                                 uint32 *smb_fflags, uint32 *smb_fmask)
3971 {
3972         int i;
3973
3974         for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
3975             *smb_fmask |= info2_flags_map[i].smb_fflag;
3976             if (psbuf->st_ex_flags & info2_flags_map[i].stat_fflag) {
3977                     *smb_fflags |= info2_flags_map[i].smb_fflag;
3978             }
3979         }
3980 }
3981
3982 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
3983                                 const uint32 smb_fflags,
3984                                 const uint32 smb_fmask,
3985                                 int *stat_fflags)
3986 {
3987         uint32 max_fmask = 0;
3988         int i;
3989
3990         *stat_fflags = psbuf->st_ex_flags;
3991
3992         /* For each flags requested in smb_fmask, check the state of the
3993          * corresponding flag in smb_fflags and set or clear the matching
3994          * stat flag.
3995          */
3996
3997         for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
3998             max_fmask |= info2_flags_map[i].smb_fflag;
3999             if (smb_fmask & info2_flags_map[i].smb_fflag) {
4000                     if (smb_fflags & info2_flags_map[i].smb_fflag) {
4001                             *stat_fflags |= info2_flags_map[i].stat_fflag;
4002                     } else {
4003                             *stat_fflags &= ~info2_flags_map[i].stat_fflag;
4004                     }
4005             }
4006         }
4007
4008         /* If smb_fmask is asking to set any bits that are not supported by
4009          * our flag mappings, we should fail.
4010          */
4011         if ((smb_fmask & max_fmask) != smb_fmask) {
4012                 return False;
4013         }
4014
4015         return True;
4016 }
4017
4018
4019 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
4020  * of file flags and birth (create) time.
4021  */
4022 static char *store_file_unix_basic_info2(connection_struct *conn,
4023                                 char *pdata,
4024                                 files_struct *fsp,
4025                                 const SMB_STRUCT_STAT *psbuf)
4026 {
4027         uint32 file_flags = 0;
4028         uint32 flags_mask = 0;
4029
4030         pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
4031
4032         /* Create (birth) time 64 bit */
4033         put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER,pdata, psbuf->st_ex_btime);
4034         pdata += 8;
4035
4036         map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
4037         SIVAL(pdata, 0, file_flags); /* flags */
4038         SIVAL(pdata, 4, flags_mask); /* mask */
4039         pdata += 8;
4040
4041         return pdata;
4042 }
4043
4044 static NTSTATUS marshall_stream_info(unsigned int num_streams,
4045                                      const struct stream_struct *streams,
4046                                      char *data,
4047                                      unsigned int max_data_bytes,
4048                                      unsigned int *data_size)
4049 {
4050         unsigned int i;
4051         unsigned int ofs = 0;
4052
4053         for (i = 0; i < num_streams && ofs <= max_data_bytes; i++) {
4054                 unsigned int next_offset;
4055                 size_t namelen;
4056                 smb_ucs2_t *namebuf;
4057
4058                 if (!push_ucs2_talloc(talloc_tos(), &namebuf,
4059                                       streams[i].name, &namelen) ||
4060                     namelen <= 2)
4061                 {
4062                         return NT_STATUS_INVALID_PARAMETER;
4063                 }
4064
4065                 /*
4066                  * name_buf is now null-terminated, we need to marshall as not
4067                  * terminated
4068                  */
4069
4070                 namelen -= 2;
4071
4072                 SIVAL(data, ofs+4, namelen);
4073                 SOFF_T(data, ofs+8, streams[i].size);
4074                 SOFF_T(data, ofs+16, streams[i].alloc_size);
4075                 memcpy(data+ofs+24, namebuf, namelen);
4076                 TALLOC_FREE(namebuf);
4077
4078                 next_offset = ofs + 24 + namelen;
4079
4080                 if (i == num_streams-1) {
4081                         SIVAL(data, ofs, 0);
4082                 }
4083                 else {
4084                         unsigned int align = ndr_align_size(next_offset, 8);
4085
4086                         memset(data+next_offset, 0, align);
4087                         next_offset += align;
4088
4089                         SIVAL(data, ofs, next_offset - ofs);
4090                         ofs = next_offset;
4091                 }
4092
4093                 ofs = next_offset;
4094         }
4095
4096         *data_size = ofs;
4097
4098         return NT_STATUS_OK;
4099 }
4100
4101 /****************************************************************************
4102  Reply to a TRANSACT2_QFILEINFO on a PIPE !
4103 ****************************************************************************/
4104
4105 static void call_trans2qpipeinfo(connection_struct *conn,
4106                                  struct smb_request *req,
4107                                  unsigned int tran_call,
4108                                  char **pparams, int total_params,
4109                                  char **ppdata, int total_data,
4110                                  unsigned int max_data_bytes)
4111 {
4112         char *params = *pparams;
4113         char *pdata = *ppdata;
4114         unsigned int data_size = 0;
4115         unsigned int param_size = 2;
4116         uint16 info_level;
4117         files_struct *fsp;
4118
4119         if (!params) {
4120                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4121                 return;
4122         }
4123
4124         if (total_params < 4) {
4125                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4126                 return;
4127         }
4128
4129         fsp = file_fsp(req, SVAL(params,0));
4130         if (!fsp_is_np(fsp)) {
4131                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
4132                 return;
4133         }
4134
4135         info_level = SVAL(params,2);
4136
4137         *pparams = (char *)SMB_REALLOC(*pparams,2);
4138         if (*pparams == NULL) {
4139                 reply_nterror(req, NT_STATUS_NO_MEMORY);
4140                 return;
4141         }
4142         params = *pparams;
4143         SSVAL(params,0,0);
4144         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
4145         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 
4146         if (*ppdata == NULL ) {
4147                 reply_nterror(req, NT_STATUS_NO_MEMORY);
4148                 return;
4149         }
4150         pdata = *ppdata;
4151
4152         switch (info_level) {
4153                 case SMB_FILE_STANDARD_INFORMATION:
4154                         memset(pdata,0,24);
4155                         SOFF_T(pdata,0,4096LL);
4156                         SIVAL(pdata,16,1);
4157                         SIVAL(pdata,20,1);
4158                         data_size = 24;
4159                         break;
4160
4161                 default:
4162                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
4163                         return;
4164         }
4165
4166         send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
4167                             max_data_bytes);
4168
4169         return;
4170 }
4171
4172 NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
4173                                TALLOC_CTX *mem_ctx,
4174                                uint16_t info_level,
4175                                files_struct *fsp,
4176                                struct smb_filename *smb_fname,
4177                                bool delete_pending,
4178                                struct timespec write_time_ts,
4179                                struct ea_list *ea_list,
4180                                int lock_data_count,
4181                                char *lock_data,
4182                                uint16_t flags2,
4183                                unsigned int max_data_bytes,
4184                                char **ppdata,
4185                                unsigned int *pdata_size)
4186 {
4187         char *pdata = *ppdata;
4188         char *dstart, *dend;
4189         unsigned int data_size;
4190         struct timespec create_time_ts, mtime_ts, atime_ts, ctime_ts;
4191         time_t create_time, mtime, atime, c_time;
4192         SMB_STRUCT_STAT *psbuf = &smb_fname->st;
4193         char *p;
4194         char *base_name;
4195         char *dos_fname;
4196         int mode;
4197         int nlink;
4198         NTSTATUS status;
4199         uint64_t file_size = 0;
4200         uint64_t pos = 0;
4201         uint64_t allocation_size = 0;
4202         uint64_t file_index = 0;
4203         uint32_t access_mask = 0;
4204
4205         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
4206                 return NT_STATUS_INVALID_LEVEL;
4207         }
4208
4209         DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n",
4210                  smb_fname_str_dbg(smb_fname), fsp ? fsp->fnum : -1,
4211                  info_level, max_data_bytes));
4212
4213         mode = dos_mode(conn, smb_fname);
4214         nlink = psbuf->st_ex_nlink;
4215
4216         if (nlink && (mode&aDIR)) {
4217                 nlink = 1;
4218         }
4219
4220         if ((nlink > 0) && delete_pending) {
4221                 nlink -= 1;
4222         }
4223
4224         data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
4225         *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 
4226         if (*ppdata == NULL) {
4227                 return NT_STATUS_NO_MEMORY;
4228         }
4229         pdata = *ppdata;
4230         dstart = pdata;
4231         dend = dstart + data_size - 1;
4232
4233         if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
4234                 update_stat_ex_mtime(psbuf, write_time_ts);
4235         }
4236
4237         create_time_ts = get_create_timespec(conn, fsp, smb_fname);
4238         mtime_ts = psbuf->st_ex_mtime;
4239         atime_ts = psbuf->st_ex_atime;
4240         ctime_ts = get_change_timespec(conn, fsp, smb_fname);
4241
4242         if (lp_dos_filetime_resolution(SNUM(conn))) {
4243                 dos_filetime_timespec(&create_time_ts);
4244                 dos_filetime_timespec(&mtime_ts);
4245                 dos_filetime_timespec(&atime_ts);
4246                 dos_filetime_timespec(&ctime_ts);
4247         }
4248
4249         create_time = convert_timespec_to_time_t(create_time_ts);
4250         mtime = convert_timespec_to_time_t(mtime_ts);
4251         atime = convert_timespec_to_time_t(atime_ts);
4252         c_time = convert_timespec_to_time_t(ctime_ts);
4253
4254         p = strrchr_m(smb_fname->base_name,'/');
4255         if (!p)
4256                 base_name = smb_fname->base_name;
4257         else
4258                 base_name = p+1;
4259
4260         /* NT expects the name to be in an exact form of the *full*
4261            filename. See the trans2 torture test */
4262         if (ISDOT(base_name)) {
4263                 dos_fname = talloc_strdup(mem_ctx, "\\");
4264                 if (!dos_fname) {
4265                         return NT_STATUS_NO_MEMORY;
4266                 }
4267         } else {
4268                 dos_fname = talloc_asprintf(mem_ctx,
4269                                 "\\%s",
4270                                 smb_fname->base_name);
4271                 if (!dos_fname) {
4272                         return NT_STATUS_NO_MEMORY;
4273                 }
4274                 if (is_ntfs_stream_smb_fname(smb_fname)) {
4275                         dos_fname = talloc_asprintf(dos_fname, "%s",
4276                                                     smb_fname->stream_name);
4277                         if (!dos_fname) {
4278                                 return NT_STATUS_NO_MEMORY;
4279                         }
4280                 }
4281
4282                 string_replace(dos_fname, '/', '\\');
4283         }
4284
4285         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, psbuf);
4286
4287         if (!fsp) {
4288                 /* Do we have this path open ? */
4289                 files_struct *fsp1;
4290                 struct file_id fileid = vfs_file_id_from_sbuf(conn, psbuf);
4291                 fsp1 = file_find_di_first(fileid);
4292                 if (fsp1 && fsp1->initial_allocation_size) {
4293                         allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, psbuf);
4294                 }
4295         }
4296
4297         if (!(mode & aDIR)) {
4298                 file_size = get_file_size_stat(psbuf);
4299         }
4300
4301         if (fsp) {
4302                 pos = fsp->fh->position_information;
4303         }
4304
4305         if (fsp) {
4306                 access_mask = fsp->access_mask;
4307         } else {
4308                 /* GENERIC_EXECUTE mapping from Windows */
4309                 access_mask = 0x12019F;
4310         }
4311
4312         /* This should be an index number - looks like
4313            dev/ino to me :-)
4314
4315            I think this causes us to fail the IFSKIT
4316            BasicFileInformationTest. -tpot */
4317         file_index =  ((psbuf->st_ex_ino) & UINT32_MAX); /* FileIndexLow */
4318         file_index |= ((uint64_t)((psbuf->st_ex_dev) & UINT32_MAX)) << 32; /* FileIndexHigh */
4319
4320         switch (info_level) {
4321                 case SMB_INFO_STANDARD:
4322                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
4323                         data_size = 22;
4324                         srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
4325                         srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
4326                         srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
4327                         SIVAL(pdata,l1_cbFile,(uint32)file_size);
4328                         SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
4329                         SSVAL(pdata,l1_attrFile,mode);
4330                         break;
4331
4332                 case SMB_INFO_QUERY_EA_SIZE:
4333                 {
4334                         unsigned int ea_size =
4335                             estimate_ea_size(conn, fsp,
4336                                              smb_fname->base_name);
4337                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
4338                         data_size = 26;
4339                         srv_put_dos_date2(pdata,0,create_time);
4340                         srv_put_dos_date2(pdata,4,atime);
4341                         srv_put_dos_date2(pdata,8,mtime); /* write time */
4342                         SIVAL(pdata,12,(uint32)file_size);
4343                         SIVAL(pdata,16,(uint32)allocation_size);
4344                         SSVAL(pdata,20,mode);
4345                         SIVAL(pdata,22,ea_size);
4346                         break;
4347                 }
4348
4349                 case SMB_INFO_IS_NAME_VALID:
4350                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
4351                         if (fsp) {
4352                                 /* os/2 needs this ? really ?*/
4353                                 return NT_STATUS_DOS(ERRDOS, ERRbadfunc);
4354                         }
4355                         /* This is only reached for qpathinfo */
4356                         data_size = 0;
4357                         break;
4358
4359                 case SMB_INFO_QUERY_EAS_FROM_LIST:
4360                 {
4361                         size_t total_ea_len = 0;
4362                         struct ea_list *ea_file_list = NULL;
4363
4364                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
4365
4366                         ea_file_list =
4367                             get_ea_list_from_file(mem_ctx, conn, fsp,
4368                                                   smb_fname->base_name,
4369                                                   &total_ea_len);
4370                         ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
4371
4372                         if (!ea_list || (total_ea_len > data_size)) {
4373                                 data_size = 4;
4374                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
4375                                 break;
4376                         }
4377
4378                         data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
4379                         break;
4380                 }
4381
4382                 case SMB_INFO_QUERY_ALL_EAS:
4383                 {
4384                         /* We have data_size bytes to put EA's into. */
4385                         size_t total_ea_len = 0;
4386
4387                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
4388
4389                         ea_list = get_ea_list_from_file(mem_ctx, conn, fsp,
4390                                                         smb_fname->base_name,
4391                                                         &total_ea_len);
4392                         if (!ea_list || (total_ea_len > data_size)) {
4393                                 data_size = 4;
4394                                 SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
4395                                 break;
4396                         }
4397
4398                         data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
4399                         break;
4400                 }
4401
4402                 case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
4403                 {
4404                         /* This is FileFullEaInformation - 0xF which maps to
4405                          * 1015 (decimal) in smbd_do_setfilepathinfo. */
4406
4407                         /* We have data_size bytes to put EA's into. */
4408                         size_t total_ea_len = 0;
4409                         struct ea_list *ea_file_list = NULL;
4410
4411                         DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
4412
4413                         /*TODO: add filtering and index handling */
4414
4415                         ea_file_list =
4416                             get_ea_list_from_file(mem_ctx, conn, fsp,
4417                                                   smb_fname->base_name,
4418                                                   &total_ea_len);
4419                         if (!ea_file_list) {
4420                                 return NT_STATUS_NO_EAS_ON_FILE;
4421                         }
4422
4423                         status = fill_ea_chained_buffer(mem_ctx,
4424                                                         pdata,
4425                                                         data_size,
4426                                                         &data_size,
4427                                                         conn, ea_file_list);
4428                         if (!NT_STATUS_IS_OK(status)) {
4429                                 return status;
4430                         }
4431                         break;
4432                 }
4433
4434                 case SMB_FILE_BASIC_INFORMATION:
4435                 case SMB_QUERY_FILE_BASIC_INFO:
4436
4437                         if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
4438                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
4439                                 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
4440                         } else {
4441                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
4442                                 data_size = 40;
4443                                 SIVAL(pdata,36,0);
4444                         }
4445                         put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
4446                         put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
4447                         put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
4448                         put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
4449                         SIVAL(pdata,32,mode);
4450
4451                         DEBUG(5,("SMB_QFBI - "));
4452                         DEBUG(5,("create: %s ", ctime(&create_time)));
4453                         DEBUG(5,("access: %s ", ctime(&atime)));
4454                         DEBUG(5,("write: %s ", ctime(&mtime)));
4455                         DEBUG(5,("change: %s ", ctime(&c_time)));
4456                         DEBUG(5,("mode: %x\n", mode));
4457                         break;
4458
4459                 case SMB_FILE_STANDARD_INFORMATION:
4460                 case SMB_QUERY_FILE_STANDARD_INFO:
4461
4462                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
4463                         data_size = 24;
4464                         SOFF_T(pdata,0,allocation_size);
4465                         SOFF_T(pdata,8,file_size);
4466                         SIVAL(pdata,16,nlink);
4467                         SCVAL(pdata,20,delete_pending?1:0);
4468                         SCVAL(pdata,21,(mode&aDIR)?1:0);
4469                         SSVAL(pdata,22,0); /* Padding. */
4470                         break;
4471
4472                 case SMB_FILE_EA_INFORMATION:
4473                 case SMB_QUERY_FILE_EA_INFO:
4474                 {
4475                         unsigned int ea_size =
4476                             estimate_ea_size(conn, fsp, smb_fname->base_name);
4477                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
4478                         data_size = 4;
4479                         SIVAL(pdata,0,ea_size);
4480                         break;
4481                 }
4482
4483                 /* Get the 8.3 name - used if NT SMB was negotiated. */
4484                 case SMB_QUERY_FILE_ALT_NAME_INFO:
4485                 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
4486                 {
4487                         int len;
4488                         char mangled_name[13];
4489                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
4490                         if (!name_to_8_3(base_name,mangled_name,
4491                                                 True,conn->params)) {
4492                                 return NT_STATUS_NO_MEMORY;
4493                         }
4494                         len = srvstr_push(dstart, flags2,
4495                                           pdata+4, mangled_name,
4496                                           PTR_DIFF(dend, pdata+4),
4497                                           STR_UNICODE);
4498                         data_size = 4 + len;
4499                         SIVAL(pdata,0,len);
4500                         break;
4501                 }
4502
4503                 case SMB_QUERY_FILE_NAME_INFO:
4504                 {
4505                         int len;
4506                         /*
4507                           this must be *exactly* right for ACLs on mapped drives to work
4508                          */
4509                         len = srvstr_push(dstart, flags2,
4510                                           pdata+4, dos_fname,
4511                                           PTR_DIFF(dend, pdata+4),
4512                                           STR_UNICODE);
4513                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
4514                         data_size = 4 + len;
4515                         SIVAL(pdata,0,len);
4516                         break;
4517                 }
4518
4519                 case SMB_FILE_ALLOCATION_INFORMATION:
4520                 case SMB_QUERY_FILE_ALLOCATION_INFO:
4521                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
4522                         data_size = 8;
4523                         SOFF_T(pdata,0,allocation_size);
4524                         break;
4525
4526                 case SMB_FILE_END_OF_FILE_INFORMATION:
4527                 case SMB_QUERY_FILE_END_OF_FILEINFO:
4528                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
4529                         data_size = 8;
4530                         SOFF_T(pdata,0,file_size);
4531                         break;
4532
4533                 case SMB_QUERY_FILE_ALL_INFO:
4534                 case SMB_FILE_ALL_INFORMATION:
4535                 {
4536                         int len;
4537                         unsigned int ea_size =
4538                             estimate_ea_size(conn, fsp, smb_fname->base_name);
4539                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
4540                         put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
4541                         put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
4542                         put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
4543                         put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
4544                         SIVAL(pdata,32,mode);
4545                         SIVAL(pdata,36,0); /* padding. */
4546                         pdata += 40;
4547                         SOFF_T(pdata,0,allocation_size);
4548                         SOFF_T(pdata,8,file_size);
4549                         SIVAL(pdata,16,nlink);
4550                         SCVAL(pdata,20,delete_pending);
4551                         SCVAL(pdata,21,(mode&aDIR)?1:0);
4552                         SSVAL(pdata,22,0);
4553                         pdata += 24;
4554                         SIVAL(pdata,0,ea_size);
4555                         pdata += 4; /* EA info */
4556                         len = srvstr_push(dstart, flags2,
4557                                           pdata+4, dos_fname,
4558                                           PTR_DIFF(dend, pdata+4),
4559                                           STR_UNICODE);
4560                         SIVAL(pdata,0,len);
4561                         pdata += 4 + len;
4562                         data_size = PTR_DIFF(pdata,(*ppdata));
4563                         break;
4564                 }
4565
4566                 case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
4567                 {
4568                         int len;
4569                         unsigned int ea_size =
4570                             estimate_ea_size(conn, fsp, smb_fname->base_name);
4571                         DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
4572                         put_long_date_timespec(conn->ts_res,pdata+0x00,create_time_ts);
4573                         put_long_date_timespec(conn->ts_res,pdata+0x08,atime_ts);
4574                         put_long_date_timespec(conn->ts_res,pdata+0x10,mtime_ts); /* write time */
4575                         put_long_date_timespec(conn->ts_res,pdata+0x18,ctime_ts); /* change time */
4576                         SIVAL(pdata,    0x20, mode);
4577                         SIVAL(pdata,    0x24, 0); /* padding. */
4578                         SBVAL(pdata,    0x28, allocation_size);
4579                         SBVAL(pdata,    0x30, file_size);
4580                         SIVAL(pdata,    0x38, nlink);
4581                         SCVAL(pdata,    0x3C, delete_pending);
4582                         SCVAL(pdata,    0x3D, (mode&aDIR)?1:0);
4583                         SSVAL(pdata,    0x3E, 0); /* padding */
4584                         SBVAL(pdata,    0x40, file_index);
4585                         SIVAL(pdata,    0x48, ea_size);
4586                         SIVAL(pdata,    0x4C, access_mask);
4587                         SBVAL(pdata,    0x50, pos);
4588                         SIVAL(pdata,    0x58, mode); /*TODO: mode != mode fix this!!! */
4589                         SIVAL(pdata,    0x5C, 0); /* No alignment needed. */
4590
4591                         pdata += 0x60;
4592
4593                         len = srvstr_push(dstart, flags2,
4594                                           pdata+4, dos_fname,
4595                                           PTR_DIFF(dend, pdata+4),
4596                                           STR_UNICODE);
4597                         SIVAL(pdata,0,len);
4598                         pdata += 4 + len;
4599                         data_size = PTR_DIFF(pdata,(*ppdata));
4600                         break;
4601                 }
4602                 case SMB_FILE_INTERNAL_INFORMATION:
4603
4604                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
4605                         SBVAL(pdata, 0, file_index);
4606                         data_size = 8;
4607                         break;
4608
4609                 case SMB_FILE_ACCESS_INFORMATION:
4610                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
4611                         SIVAL(pdata, 0, access_mask);
4612                         data_size = 4;
4613                         break;
4614
4615                 case SMB_FILE_NAME_INFORMATION:
4616                         /* Pathname with leading '\'. */
4617                         {
4618                                 size_t byte_len;
4619                                 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
4620                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
4621                                 SIVAL(pdata,0,byte_len);
4622                                 data_size = 4 + byte_len;
4623                                 break;
4624                         }
4625
4626                 case SMB_FILE_DISPOSITION_INFORMATION:
4627                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
4628                         data_size = 1;
4629                         SCVAL(pdata,0,delete_pending);
4630                         break;
4631
4632                 case SMB_FILE_POSITION_INFORMATION:
4633                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
4634                         data_size = 8;
4635                         SOFF_T(pdata,0,pos);
4636                         break;
4637
4638                 case SMB_FILE_MODE_INFORMATION:
4639                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
4640                         SIVAL(pdata,0,mode);
4641                         data_size = 4;
4642                         break;
4643
4644                 case SMB_FILE_ALIGNMENT_INFORMATION:
4645                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
4646                         SIVAL(pdata,0,0); /* No alignment needed. */
4647                         data_size = 4;
4648                         break;
4649
4650                 /*
4651                  * NT4 server just returns "invalid query" to this - if we try
4652                  * to answer it then NTws gets a BSOD! (tridge).  W2K seems to
4653                  * want this. JRA.
4654                  */
4655                 /* The first statement above is false - verified using Thursby
4656                  * client against NT4 -- gcolley.
4657                  */
4658                 case SMB_QUERY_FILE_STREAM_INFO:
4659                 case SMB_FILE_STREAM_INFORMATION: {
4660                         unsigned int num_streams;
4661                         struct stream_struct *streams;
4662
4663                         DEBUG(10,("smbd_do_qfilepathinfo: "
4664                                   "SMB_FILE_STREAM_INFORMATION\n"));
4665
4666                         if (is_ntfs_stream_smb_fname(smb_fname)) {
4667                                 return NT_STATUS_INVALID_PARAMETER;
4668                         }
4669
4670                         status = SMB_VFS_STREAMINFO(
4671                                 conn, fsp, smb_fname->base_name, talloc_tos(),
4672                                 &num_streams, &streams);
4673
4674                         if (!NT_STATUS_IS_OK(status)) {
4675                                 DEBUG(10, ("could not get stream info: %s\n",
4676                                            nt_errstr(status)));
4677                                 return status;
4678                         }
4679
4680                         status = marshall_stream_info(num_streams, streams,
4681                                                       pdata, max_data_bytes,
4682                                                       &data_size);
4683
4684                         if (!NT_STATUS_IS_OK(status)) {
4685                                 DEBUG(10, ("marshall_stream_info failed: %s\n",
4686                                            nt_errstr(status)));
4687                                 return status;
4688                         }
4689
4690                         TALLOC_FREE(streams);
4691
4692                         break;
4693                 }
4694                 case SMB_QUERY_COMPRESSION_INFO:
4695                 case SMB_FILE_COMPRESSION_INFORMATION:
4696                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
4697                         SOFF_T(pdata,0,file_size);
4698                         SIVAL(pdata,8,0); /* ??? */
4699                         SIVAL(pdata,12,0); /* ??? */
4700                         data_size = 16;
4701                         break;
4702
4703                 case SMB_FILE_NETWORK_OPEN_INFORMATION:
4704                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
4705                         put_long_date_timespec(conn->ts_res,pdata,create_time_ts);
4706                         put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
4707                         put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
4708                         put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
4709                         SOFF_T(pdata,32,allocation_size);
4710                         SOFF_T(pdata,40,file_size);
4711                         SIVAL(pdata,48,mode);
4712                         SIVAL(pdata,52,0); /* ??? */
4713                         data_size = 56;
4714                         break;
4715
4716                 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
4717                         DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
4718                         SIVAL(pdata,0,mode);
4719                         SIVAL(pdata,4,0);
4720                         data_size = 8;
4721                         break;
4722
4723                 /*
4724                  * CIFS UNIX Extensions.
4725                  */
4726
4727                 case SMB_QUERY_FILE_UNIX_BASIC:
4728
4729                         pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
4730                         data_size = PTR_DIFF(pdata,(*ppdata));
4731
4732                         {
4733                                 int i;
4734                                 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
4735
4736                                 for (i=0; i<100; i++)
4737                                         DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
4738                                 DEBUG(4,("\n"));
4739                         }
4740
4741                         break;
4742
4743                 case SMB_QUERY_FILE_UNIX_INFO2:
4744
4745                         pdata = store_file_unix_basic_info2(conn, pdata, fsp, psbuf);
4746                         data_size = PTR_DIFF(pdata,(*ppdata));
4747
4748                         {
4749                                 int i;
4750                                 DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
4751
4752                                 for (i=0; i<100; i++)
4753                                         DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
4754                                 DEBUG(4,("\n"));
4755                         }
4756
4757                         break;
4758
4759                 case SMB_QUERY_FILE_UNIX_LINK:
4760                         {
4761                                 int len;
4762                                 char *buffer = TALLOC_ARRAY(mem_ctx, char, PATH_MAX+1);
4763
4764                                 if (!buffer) {
4765                                         return NT_STATUS_NO_MEMORY;
4766                                 }
4767
4768                                 DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
4769 #ifdef S_ISLNK
4770                                 if(!S_ISLNK(psbuf->st_ex_mode)) {
4771                                         return NT_STATUS_DOS(ERRSRV, ERRbadlink);
4772                                 }
4773 #else
4774                                 return NT_STATUS_DOS(ERRDOS, ERRbadlink);
4775 #endif
4776                                 len = SMB_VFS_READLINK(conn,
4777                                                        smb_fname->base_name,
4778                                                        buffer, PATH_MAX);
4779                                 if (len == -1) {
4780                                         return map_nt_error_from_unix(errno);
4781                                 }
4782                                 buffer[len] = 0;
4783                                 len = srvstr_push(dstart, flags2,
4784                                                   pdata, buffer,
4785                                                   PTR_DIFF(dend, pdata),
4786                                                   STR_TERMINATE);
4787                                 pdata += len;
4788                                 data_size = PTR_DIFF(pdata,(*ppdata));
4789
4790                                 break;
4791                         }
4792
4793 #if defined(HAVE_POSIX_ACLS)
4794                 case SMB_QUERY_POSIX_ACL:
4795                         {
4796                                 SMB_ACL_T file_acl = NULL;
4797                                 SMB_ACL_T def_acl = NULL;
4798                                 uint16 num_file_acls = 0;
4799                                 uint16 num_def_acls = 0;
4800
4801                                 if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) {
4802                                         file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp);
4803                                 } else {
4804                                         file_acl =
4805                                             SMB_VFS_SYS_ACL_GET_FILE(conn,
4806                                                 smb_fname->base_name,
4807                                                 SMB_ACL_TYPE_ACCESS);
4808                                 }
4809
4810                                 if (file_acl == NULL && no_acl_syscall_error(errno)) {
4811                                         DEBUG(5,("smbd_do_qfilepathinfo: ACLs "
4812                                                  "not implemented on "
4813                                                  "filesystem containing %s\n",
4814                                                  smb_fname->base_name));
4815                                         return NT_STATUS_NOT_IMPLEMENTED;
4816                                 }
4817
4818                                 if (S_ISDIR(psbuf->st_ex_mode)) {
4819                                         if (fsp && fsp->is_directory) {
4820                                                 def_acl =
4821                                                     SMB_VFS_SYS_ACL_GET_FILE(
4822                                                             conn,
4823                                                             fsp->fsp_name->base_name,
4824                                                             SMB_ACL_TYPE_DEFAULT);
4825                                         } else {
4826                                                 def_acl =
4827                                                     SMB_VFS_SYS_ACL_GET_FILE(
4828                                                             conn,
4829                                                             smb_fname->base_name,
4830                                                             SMB_ACL_TYPE_DEFAULT);
4831                                         }
4832                                         def_acl = free_empty_sys_acl(conn, def_acl);
4833                                 }
4834
4835                                 num_file_acls = count_acl_entries(conn, file_acl);
4836                                 num_def_acls = count_acl_entries(conn, def_acl);
4837
4838                                 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
4839                                         DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n",
4840                                                 data_size,
4841                                                 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
4842                                                         SMB_POSIX_ACL_HEADER_SIZE) ));
4843                                         if (file_acl) {
4844                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4845                                         }
4846                                         if (def_acl) {
4847                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4848                                         }
4849                                         return NT_STATUS_BUFFER_TOO_SMALL;
4850                                 }
4851
4852                                 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
4853                                 SSVAL(pdata,2,num_file_acls);
4854                                 SSVAL(pdata,4,num_def_acls);
4855                                 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, psbuf, file_acl)) {
4856                                         if (file_acl) {
4857                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4858                                         }
4859                                         if (def_acl) {
4860                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4861                                         }
4862                                         return NT_STATUS_INTERNAL_ERROR;
4863                                 }
4864                                 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), psbuf, def_acl)) {
4865                                         if (file_acl) {
4866                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4867                                         }
4868                                         if (def_acl) {
4869                                                 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4870                                         }
4871                                         return NT_STATUS_INTERNAL_ERROR;
4872                                 }
4873
4874                                 if (file_acl) {
4875                                         SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
4876                                 }
4877                                 if (def_acl) {
4878                                         SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
4879                                 }
4880                                 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
4881                                 break;
4882                         }
4883 #endif
4884
4885
4886                 case SMB_QUERY_POSIX_LOCK:
4887                 {
4888                         uint64_t count;
4889                         uint64_t offset;
4890                         uint64_t smblctx;
4891                         enum brl_type lock_type;
4892
4893                         /* We need an open file with a real fd for this. */
4894                         if (!fsp || fsp->is_directory || fsp->fh->fd == -1) {
4895                                 return NT_STATUS_INVALID_LEVEL;
4896                         }
4897
4898                         if (lock_data_count != POSIX_LOCK_DATA_SIZE) {
4899                                 return NT_STATUS_INVALID_PARAMETER;
4900                         }
4901
4902                         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
4903                                 case POSIX_LOCK_TYPE_READ:
4904                                         lock_type = READ_LOCK;
4905                                         break;
4906                                 case POSIX_LOCK_TYPE_WRITE:
4907                                         lock_type = WRITE_LOCK;
4908                                         break;
4909                                 case POSIX_LOCK_TYPE_UNLOCK:
4910                                 default:
4911                                         /* There's no point in asking for an unlock... */
4912                                         return NT_STATUS_INVALID_PARAMETER;
4913                         }
4914
4915                         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
4916 #if defined(HAVE_LONGLONG)
4917                         offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
4918                                         ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
4919                         count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
4920                                         ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
4921 #else /* HAVE_LONGLONG */
4922                         offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET);
4923                         count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
4924 #endif /* HAVE_LONGLONG */
4925
4926                         status = query_lock(fsp,
4927                                         &smblctx,
4928                                         &count,
4929                                         &offset,
4930                                         &lock_type,
4931                                         POSIX_LOCK);
4932
4933                         if (ERROR_WAS_LOCK_DENIED(status)) {
4934                                 /* Here we need to report who has it locked... */
4935                                 data_size = POSIX_LOCK_DATA_SIZE;
4936
4937                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
4938                                 SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
4939                                 SIVAL(pdata, POSIX_LOCK_PID_OFFSET, (uint32_t)smblctx);
4940 #if defined(HAVE_LONGLONG)
4941                                 SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF));
4942                                 SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF));
4943                                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF));
4944                                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF));
4945 #else /* HAVE_LONGLONG */
4946                                 SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
4947                                 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
4948 #endif /* HAVE_LONGLONG */
4949
4950                         } else if (NT_STATUS_IS_OK(status)) {
4951                                 /* For success we just return a copy of what we sent
4952                                    with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
4953                                 data_size = POSIX_LOCK_DATA_SIZE;
4954                                 memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
4955                                 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
4956                         } else {
4957                                 return status;
4958                         }
4959                         break;
4960                 }
4961
4962                 default:
4963                         return NT_STATUS_INVALID_LEVEL;
4964         }
4965
4966         *pdata_size = data_size;
4967         return NT_STATUS_OK;
4968 }
4969
4970 /****************************************************************************
4971  Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
4972  file name or file id).
4973 ****************************************************************************/
4974
4975 static void call_trans2qfilepathinfo(connection_struct *conn,
4976                                      struct smb_request *req,
4977                                      unsigned int tran_call,
4978                                      char **pparams, int total_params,
4979                                      char **ppdata, int total_data,
4980                                      unsigned int max_data_bytes)
4981 {
4982         char *params = *pparams;
4983         char *pdata = *ppdata;
4984         uint16 info_level;
4985         unsigned int data_size = 0;
4986         unsigned int param_size = 2;
4987         struct smb_filename *smb_fname = NULL;
4988         bool delete_pending = False;
4989         struct timespec write_time_ts;
4990         files_struct *fsp = NULL;
4991         struct file_id fileid;
4992         struct ea_list *ea_list = NULL;
4993         int lock_data_count = 0;
4994         char *lock_data = NULL;
4995         NTSTATUS status = NT_STATUS_OK;
4996
4997         if (!params) {
4998                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4999                 return;
5000         }
5001
5002         ZERO_STRUCT(write_time_ts);
5003
5004         if (tran_call == TRANSACT2_QFILEINFO) {
5005                 if (total_params < 4) {
5006                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5007                         return;
5008                 }
5009
5010                 if (IS_IPC(conn)) {
5011                         call_trans2qpipeinfo(conn, req, tran_call,
5012                                              pparams, total_params,
5013                                              ppdata, total_data,
5014                                              max_data_bytes);
5015                         return;
5016                 }
5017
5018                 fsp = file_fsp(req, SVAL(params,0));
5019                 info_level = SVAL(params,2);
5020
5021                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
5022
5023                 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
5024                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5025                         return;
5026                 }
5027
5028                 /* Initial check for valid fsp ptr. */
5029                 if (!check_fsp_open(conn, req, fsp)) {
5030                         return;
5031                 }
5032
5033                 status = copy_smb_filename(talloc_tos(), fsp->fsp_name,
5034                                            &smb_fname);
5035                 if (!NT_STATUS_IS_OK(status)) {
5036                         reply_nterror(req, status);
5037                         return;
5038                 }
5039
5040                 if(fsp->fake_file_handle) {
5041                         /*
5042                          * This is actually for the QUOTA_FAKE_FILE --metze
5043                          */
5044
5045                         /* We know this name is ok, it's already passed the checks. */
5046
5047                 } else if(fsp->is_directory || fsp->fh->fd == -1) {
5048                         /*
5049                          * This is actually a QFILEINFO on a directory
5050                          * handle (returned from an NT SMB). NT5.0 seems
5051                          * to do this call. JRA.
5052                          */
5053
5054                         if (INFO_LEVEL_IS_UNIX(info_level)) {
5055                                 /* Always do lstat for UNIX calls. */
5056                                 if (SMB_VFS_LSTAT(conn, smb_fname)) {
5057                                         DEBUG(3,("call_trans2qfilepathinfo: "
5058                                                  "SMB_VFS_LSTAT of %s failed "
5059                                                  "(%s)\n",
5060                                                  smb_fname_str_dbg(smb_fname),
5061                                                  strerror(errno)));
5062                                         reply_nterror(req,
5063                                                 map_nt_error_from_unix(errno));
5064                                         return;
5065                                 }
5066                         } else if (SMB_VFS_STAT(conn, smb_fname)) {
5067                                 DEBUG(3,("call_trans2qfilepathinfo: "
5068                                          "SMB_VFS_STAT of %s failed (%s)\n",
5069                                          smb_fname_str_dbg(smb_fname),
5070                                          strerror(errno)));
5071                                 reply_nterror(req,
5072                                         map_nt_error_from_unix(errno));
5073                                 return;
5074                         }
5075
5076                         fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
5077                         get_file_infos(fileid, &delete_pending, &write_time_ts);
5078                 } else {
5079                         /*
5080                          * Original code - this is an open file.
5081                          */
5082                         if (!check_fsp(conn, req, fsp)) {
5083                                 return;
5084                         }
5085
5086                         if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
5087                                 DEBUG(3, ("fstat of fnum %d failed (%s)\n",
5088                                           fsp->fnum, strerror(errno)));
5089                                 reply_nterror(req,
5090                                         map_nt_error_from_unix(errno));
5091                                 return;
5092                         }
5093                         fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
5094                         get_file_infos(fileid, &delete_pending, &write_time_ts);
5095                 }
5096
5097         } else {
5098                 char *fname = NULL;
5099
5100                 /* qpathinfo */
5101                 if (total_params < 7) {
5102                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5103                         return;
5104                 }
5105
5106                 info_level = SVAL(params,0);
5107
5108                 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
5109
5110                 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
5111                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5112                         return;
5113                 }
5114
5115                 srvstr_get_path(req, params, req->flags2, &fname, &params[6],
5116                                 total_params - 6,
5117                                 STR_TERMINATE, &status);
5118                 if (!NT_STATUS_IS_OK(status)) {
5119                         reply_nterror(req, status);
5120                         return;
5121                 }
5122
5123                 status = filename_convert(req,
5124                                         conn,
5125                                         req->flags2 & FLAGS2_DFS_PATHNAMES,
5126                                         fname,
5127                                         0,
5128                                         NULL,
5129                                         &smb_fname);
5130                 if (!NT_STATUS_IS_OK(status)) {
5131                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
5132                                 reply_botherror(req,
5133                                                 NT_STATUS_PATH_NOT_COVERED,
5134                                                 ERRSRV, ERRbadpath);
5135                                 return;
5136                         }
5137                         reply_nterror(req, status);
5138                         return;
5139                 }
5140
5141                 /* If this is a stream, check if there is a delete_pending. */
5142                 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5143                     && is_ntfs_stream_smb_fname(smb_fname)) {
5144                         struct smb_filename *smb_fname_base = NULL;
5145
5146                         /* Create an smb_filename with stream_name == NULL. */
5147                         status =
5148                             create_synthetic_smb_fname(talloc_tos(),
5149                                                        smb_fname->base_name,
5150                                                        NULL, NULL,
5151                                                        &smb_fname_base);
5152                         if (!NT_STATUS_IS_OK(status)) {
5153                                 reply_nterror(req, status);
5154                                 return;
5155                         }
5156
5157                         if (INFO_LEVEL_IS_UNIX(info_level)) {
5158                                 /* Always do lstat for UNIX calls. */
5159                                 if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
5160                                         DEBUG(3,("call_trans2qfilepathinfo: "
5161                                                  "SMB_VFS_LSTAT of %s failed "
5162                                                  "(%s)\n",
5163                                                  smb_fname_str_dbg(smb_fname_base),
5164                                                  strerror(errno)));
5165                                         TALLOC_FREE(smb_fname_base);
5166                                         reply_nterror(req,
5167                                                 map_nt_error_from_unix(errno));
5168                                         return;
5169                                 }
5170                         } else {
5171                                 if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
5172                                         DEBUG(3,("call_trans2qfilepathinfo: "
5173                                                  "fileinfo of %s failed "
5174                                                  "(%s)\n",
5175                                                  smb_fname_str_dbg(smb_fname_base),
5176                                                  strerror(errno)));
5177                                         TALLOC_FREE(smb_fname_base);
5178                                         reply_nterror(req,
5179                                                 map_nt_error_from_unix(errno));
5180                                         return;
5181                                 }
5182                         }
5183
5184                         fileid = vfs_file_id_from_sbuf(conn,
5185                                                        &smb_fname_base->st);
5186                         TALLOC_FREE(smb_fname_base);
5187                         get_file_infos(fileid, &delete_pending, NULL);
5188                         if (delete_pending) {
5189                                 reply_nterror(req, NT_STATUS_DELETE_PENDING);
5190                                 return;
5191                         }
5192                 }
5193
5194                 if (INFO_LEVEL_IS_UNIX(info_level)) {
5195                         /* Always do lstat for UNIX calls. */
5196                         if (SMB_VFS_LSTAT(conn, smb_fname)) {
5197                                 DEBUG(3,("call_trans2qfilepathinfo: "
5198                                          "SMB_VFS_LSTAT of %s failed (%s)\n",
5199                                          smb_fname_str_dbg(smb_fname),
5200                                          strerror(errno)));
5201                                 reply_nterror(req,
5202                                         map_nt_error_from_unix(errno));
5203                                 return;
5204                         }
5205
5206                 } else {
5207                         if (SMB_VFS_STAT(conn, smb_fname) != 0) {
5208                                 DEBUG(3,("call_trans2qfilepathinfo: "
5209                                          "SMB_VFS_STAT of %s failed (%s)\n",
5210                                          smb_fname_str_dbg(smb_fname),
5211                                          strerror(errno)));
5212                                 reply_nterror(req,
5213                                         map_nt_error_from_unix(errno));
5214                                 return;
5215                         }
5216                 }
5217
5218                 fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
5219                 get_file_infos(fileid, &delete_pending, &write_time_ts);
5220                 if (delete_pending) {
5221                         reply_nterror(req, NT_STATUS_DELETE_PENDING);
5222                         return;
5223                 }
5224         }
5225
5226         DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d "
5227                  "total_data=%d\n", smb_fname_str_dbg(smb_fname),
5228                  fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
5229
5230         /* Pull out any data sent here before we realloc. */
5231         switch (info_level) {
5232                 case SMB_INFO_QUERY_EAS_FROM_LIST:
5233                 {
5234                         /* Pull any EA list from the data portion. */
5235                         uint32 ea_size;
5236
5237                         if (total_data < 4) {
5238                                 reply_nterror(
5239                                         req, NT_STATUS_INVALID_PARAMETER);
5240                                 return;
5241                         }
5242                         ea_size = IVAL(pdata,0);
5243
5244                         if (total_data > 0 && ea_size != total_data) {
5245                                 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
5246 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
5247                                 reply_nterror(
5248                                         req, NT_STATUS_INVALID_PARAMETER);
5249                                 return;
5250                         }
5251
5252                         if (!lp_ea_support(SNUM(conn))) {
5253                                 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
5254                                 return;
5255                         }
5256
5257                         /* Pull out the list of names. */
5258                         ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4);
5259                         if (!ea_list) {
5260                                 reply_nterror(
5261                                         req, NT_STATUS_INVALID_PARAMETER);
5262                                 return;
5263                         }
5264                         break;
5265                 }
5266
5267                 case SMB_QUERY_POSIX_LOCK:
5268                 {
5269                         if (fsp == NULL || fsp->fh->fd == -1) {
5270                                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
5271                                 return;
5272                         }
5273
5274                         if (total_data != POSIX_LOCK_DATA_SIZE) {
5275                                 reply_nterror(
5276                                         req, NT_STATUS_INVALID_PARAMETER);
5277                                 return;
5278                         }
5279
5280                         /* Copy the lock range data. */
5281                         lock_data = (char *)TALLOC_MEMDUP(
5282                                 req, pdata, total_data);
5283                         if (!lock_data) {
5284                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
5285                                 return;
5286                         }
5287                         lock_data_count = total_data;
5288                 }
5289                 default:
5290                         break;
5291         }
5292
5293         *pparams = (char *)SMB_REALLOC(*pparams,2);
5294         if (*pparams == NULL) {
5295                 reply_nterror(req, NT_STATUS_NO_MEMORY);
5296                 return;
5297         }
5298         params = *pparams;
5299         SSVAL(params,0,0);
5300
5301         /*
5302          * draft-leach-cifs-v1-spec-02.txt
5303          * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
5304          * says:
5305          *
5306          *  The requested information is placed in the Data portion of the
5307          *  transaction response. For the information levels greater than 0x100,
5308          *  the transaction response has 1 parameter word which should be
5309          *  ignored by the client.
5310          *
5311          * However Windows only follows this rule for the IS_NAME_VALID call.
5312          */
5313         switch (info_level) {
5314         case SMB_INFO_IS_NAME_VALID:
5315                 param_size = 0;
5316                 break;
5317         }
5318
5319         if ((info_level & 0xFF00) == 0xFF00) {
5320                 /*
5321                  * We use levels that start with 0xFF00
5322                  * internally to represent SMB2 specific levels
5323                  */
5324                 reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5325                 return;
5326         }
5327
5328         status = smbd_do_qfilepathinfo(conn, req, info_level,
5329                                        fsp, smb_fname,
5330                                        delete_pending, write_time_ts,
5331                                        ea_list,
5332                                        lock_data_count, lock_data,
5333                                        req->flags2, max_data_bytes,
5334                                        ppdata, &data_size);
5335         if (!NT_STATUS_IS_OK(status)) {
5336                 reply_nterror(req, status);
5337                 return;
5338         }
5339
5340         send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
5341                             max_data_bytes);
5342
5343         return;
5344 }
5345
5346 /****************************************************************************
5347  Set a hard link (called by UNIX extensions and by NT rename with HARD link
5348  code.
5349 ****************************************************************************/
5350
5351 NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
5352                 connection_struct *conn,
5353                 const struct smb_filename *smb_fname_old,
5354                 const 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         /* Disallow if newname already exists. */
5364         if (VALID_STAT(smb_fname_new->st)) {
5365                 return NT_STATUS_OBJECT_NAME_COLLISION;
5366         }
5367
5368         /* No links from a directory. */
5369         if (S_ISDIR(smb_fname_old->st.st_ex_mode)) {
5370                 return NT_STATUS_FILE_IS_A_DIRECTORY;
5371         }
5372
5373         /* Setting a hardlink to/from a stream isn't currently supported. */
5374         if (is_ntfs_stream_smb_fname(smb_fname_old) ||
5375             is_ntfs_stream_smb_fname(smb_fname_new)) {
5376                 return NT_STATUS_INVALID_PARAMETER;
5377         }
5378
5379         DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
5380                   smb_fname_old->base_name, smb_fname_new->base_name));
5381
5382         if (SMB_VFS_LINK(conn, smb_fname_old->base_name,
5383                          smb_fname_new->base_name) != 0) {
5384                 status = map_nt_error_from_unix(errno);
5385                 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
5386                          nt_errstr(status), smb_fname_old->base_name,
5387                          smb_fname_new->base_name));
5388         }
5389         return status;
5390 }
5391
5392 /****************************************************************************
5393  Deal with setting the time from any of the setfilepathinfo functions.
5394 ****************************************************************************/
5395
5396 NTSTATUS smb_set_file_time(connection_struct *conn,
5397                            files_struct *fsp,
5398                            const struct smb_filename *smb_fname,
5399                            struct smb_file_time *ft,
5400                            bool setting_write_time)
5401 {
5402         struct smb_filename smb_fname_base;
5403         uint32 action =
5404                 FILE_NOTIFY_CHANGE_LAST_ACCESS
5405                 |FILE_NOTIFY_CHANGE_LAST_WRITE
5406                 |FILE_NOTIFY_CHANGE_CREATION;
5407
5408         if (!VALID_STAT(smb_fname->st)) {
5409                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5410         }
5411
5412         /* get some defaults (no modifications) if any info is zero or -1. */
5413         if (null_timespec(ft->create_time)) {
5414                 action &= ~FILE_NOTIFY_CHANGE_CREATION;
5415         }
5416
5417         if (null_timespec(ft->atime)) {
5418                 action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
5419         }
5420
5421         if (null_timespec(ft->mtime)) {
5422                 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
5423         }
5424
5425         if (!setting_write_time) {
5426                 /* ft->mtime comes from change time, not write time. */
5427                 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
5428         }
5429
5430         /* Ensure the resolution is the correct for
5431          * what we can store on this filesystem. */
5432
5433         round_timespec(conn->ts_res, &ft->create_time);
5434         round_timespec(conn->ts_res, &ft->ctime);
5435         round_timespec(conn->ts_res, &ft->atime);
5436         round_timespec(conn->ts_res, &ft->mtime);
5437
5438         DEBUG(5,("smb_set_filetime: actime: %s\n ",
5439                 time_to_asc(convert_timespec_to_time_t(ft->atime))));
5440         DEBUG(5,("smb_set_filetime: modtime: %s\n ",
5441                 time_to_asc(convert_timespec_to_time_t(ft->mtime))));
5442         DEBUG(5,("smb_set_filetime: ctime: %s\n ",
5443                 time_to_asc(convert_timespec_to_time_t(ft->ctime))));
5444         DEBUG(5,("smb_set_file_time: createtime: %s\n ",
5445                 time_to_asc(convert_timespec_to_time_t(ft->create_time))));
5446
5447         if (setting_write_time) {
5448                 /*
5449                  * This was a Windows setfileinfo on an open file.
5450                  * NT does this a lot. We also need to 
5451                  * set the time here, as it can be read by 
5452                  * FindFirst/FindNext and with the patch for bug #2045
5453                  * in smbd/fileio.c it ensures that this timestamp is
5454                  * kept sticky even after a write. We save the request
5455                  * away and will set it on file close and after a write. JRA.
5456                  */
5457
5458                 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n",
5459                           time_to_asc(convert_timespec_to_time_t(ft->mtime))));
5460
5461                 if (fsp != NULL) {
5462                         if (fsp->base_fsp) {
5463                                 set_sticky_write_time_fsp(fsp->base_fsp,
5464                                                           ft->mtime);
5465                         } else {
5466                                 set_sticky_write_time_fsp(fsp, ft->mtime);
5467                         }
5468                 } else {
5469                         set_sticky_write_time_path(
5470                                 vfs_file_id_from_sbuf(conn, &smb_fname->st),
5471                                 ft->mtime);
5472                 }
5473         }
5474
5475         DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
5476
5477         /* Always call ntimes on the base, even if a stream was passed in. */
5478         smb_fname_base = *smb_fname;
5479         smb_fname_base.stream_name = NULL;
5480
5481         if(file_ntimes(conn, &smb_fname_base, ft)!=0) {
5482                 return map_nt_error_from_unix(errno);
5483         }
5484
5485         notify_fname(conn, NOTIFY_ACTION_MODIFIED, action,
5486                      smb_fname->base_name);
5487         return NT_STATUS_OK;
5488 }
5489
5490 /****************************************************************************
5491  Deal with setting the dosmode from any of the setfilepathinfo functions.
5492 ****************************************************************************/
5493
5494 static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
5495                                      const struct smb_filename *smb_fname,
5496                                      uint32 dosmode)
5497 {
5498         struct smb_filename *smb_fname_base = NULL;
5499         NTSTATUS status;
5500
5501         if (!VALID_STAT(smb_fname->st)) {
5502                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5503         }
5504
5505         /* Always operate on the base_name, even if a stream was passed in. */
5506         status = create_synthetic_smb_fname(talloc_tos(), smb_fname->base_name,
5507                                             NULL, &smb_fname->st,
5508                                             &smb_fname_base);
5509         if (!NT_STATUS_IS_OK(status)) {
5510                 return status;
5511         }
5512
5513         if (dosmode) {
5514                 if (S_ISDIR(smb_fname_base->st.st_ex_mode)) {
5515                         dosmode |= aDIR;
5516                 } else {
5517                         dosmode &= ~aDIR;
5518                 }
5519         }
5520
5521         DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode));
5522
5523         /* check the mode isn't different, before changing it */
5524         if ((dosmode != 0) && (dosmode != dos_mode(conn, smb_fname_base))) {
5525                 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
5526                           "0x%x\n", smb_fname_str_dbg(smb_fname_base),
5527                           (unsigned int)dosmode));
5528
5529                 if(file_set_dosmode(conn, smb_fname_base, dosmode, NULL,
5530                                     false)) {
5531                         DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
5532                                  "%s failed (%s)\n",
5533                                  smb_fname_str_dbg(smb_fname_base),
5534                                  strerror(errno)));
5535                         status = map_nt_error_from_unix(errno);
5536                         goto out;
5537                 }
5538         }
5539         status = NT_STATUS_OK;
5540  out:
5541         TALLOC_FREE(smb_fname_base);
5542         return status;
5543 }
5544
5545 /****************************************************************************
5546  Deal with setting the size from any of the setfilepathinfo functions.
5547 ****************************************************************************/
5548
5549 static NTSTATUS smb_set_file_size(connection_struct *conn,
5550                                   struct smb_request *req,
5551                                   files_struct *fsp,
5552                                   const struct smb_filename *smb_fname,
5553                                   const SMB_STRUCT_STAT *psbuf,
5554                                   SMB_OFF_T size,
5555                                   bool fail_after_createfile)
5556 {
5557         NTSTATUS status = NT_STATUS_OK;
5558         struct smb_filename *smb_fname_tmp = NULL;
5559         files_struct *new_fsp = NULL;
5560
5561         if (!VALID_STAT(*psbuf)) {
5562                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5563         }
5564
5565         DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size));
5566
5567         if (size == get_file_size_stat(psbuf)) {
5568                 return NT_STATUS_OK;
5569         }
5570
5571         DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
5572                   smb_fname_str_dbg(smb_fname), (double)size));
5573
5574         if (fsp && fsp->fh->fd != -1) {
5575                 /* Handle based call. */
5576                 if (vfs_set_filelen(fsp, size) == -1) {
5577                         return map_nt_error_from_unix(errno);
5578                 }
5579                 trigger_write_time_update_immediate(fsp);
5580                 return NT_STATUS_OK;
5581         }
5582
5583         status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp);
5584         if (!NT_STATUS_IS_OK(status)) {
5585                 return status;
5586         }
5587
5588         smb_fname_tmp->st = *psbuf;
5589
5590         status = SMB_VFS_CREATE_FILE(
5591                 conn,                                   /* conn */
5592                 req,                                    /* req */
5593                 0,                                      /* root_dir_fid */
5594                 smb_fname_tmp,                          /* fname */
5595                 FILE_WRITE_DATA,                        /* access_mask */
5596                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
5597                     FILE_SHARE_DELETE),
5598                 FILE_OPEN,                              /* create_disposition*/
5599                 0,                                      /* create_options */
5600                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
5601                 FORCE_OPLOCK_BREAK_TO_NONE,             /* oplock_request */
5602                 0,                                      /* allocation_size */
5603                 0,                                      /* private_flags */
5604                 NULL,                                   /* sd */
5605                 NULL,                                   /* ea_list */
5606                 &new_fsp,                               /* result */
5607                 NULL);                                  /* pinfo */
5608
5609         TALLOC_FREE(smb_fname_tmp);
5610
5611         if (!NT_STATUS_IS_OK(status)) {
5612                 /* NB. We check for open_was_deferred in the caller. */
5613                 return status;
5614         }
5615
5616         /* See RAW-SFILEINFO-END-OF-FILE */
5617         if (fail_after_createfile) {
5618                 close_file(req, new_fsp,NORMAL_CLOSE);
5619                 return NT_STATUS_INVALID_LEVEL;
5620         }
5621
5622         if (vfs_set_filelen(new_fsp, size) == -1) {
5623                 status = map_nt_error_from_unix(errno);
5624                 close_file(req, new_fsp,NORMAL_CLOSE);
5625                 return status;
5626         }
5627
5628         trigger_write_time_update_immediate(new_fsp);
5629         close_file(req, new_fsp,NORMAL_CLOSE);
5630         return NT_STATUS_OK;
5631 }
5632
5633 /****************************************************************************
5634  Deal with SMB_INFO_SET_EA.
5635 ****************************************************************************/
5636
5637 static NTSTATUS smb_info_set_ea(connection_struct *conn,
5638                                 const char *pdata,
5639                                 int total_data,
5640                                 files_struct *fsp,
5641                                 const struct smb_filename *smb_fname)
5642 {
5643         struct ea_list *ea_list = NULL;
5644         TALLOC_CTX *ctx = NULL;
5645         NTSTATUS status = NT_STATUS_OK;
5646
5647         if (total_data < 10) {
5648
5649                 /* OS/2 workplace shell seems to send SET_EA requests of "null"
5650                    length. They seem to have no effect. Bug #3212. JRA */
5651
5652                 if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
5653                         /* We're done. We only get EA info in this call. */
5654                         return NT_STATUS_OK;
5655                 }
5656
5657                 return NT_STATUS_INVALID_PARAMETER;
5658         }
5659
5660         if (IVAL(pdata,0) > total_data) {
5661                 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
5662                         IVAL(pdata,0), (unsigned int)total_data));
5663                 return NT_STATUS_INVALID_PARAMETER;
5664         }
5665
5666         ctx = talloc_tos();
5667         ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
5668         if (!ea_list) {
5669                 return NT_STATUS_INVALID_PARAMETER;
5670         }
5671         status = set_ea(conn, fsp, smb_fname, ea_list);
5672
5673         return status;
5674 }
5675
5676 /****************************************************************************
5677  Deal with SMB_FILE_FULL_EA_INFORMATION set.
5678 ****************************************************************************/
5679
5680 static NTSTATUS smb_set_file_full_ea_info(connection_struct *conn,
5681                                 const char *pdata,
5682                                 int total_data,
5683                                 files_struct *fsp)
5684 {
5685         struct ea_list *ea_list = NULL;
5686         NTSTATUS status;
5687
5688         if (!fsp) {
5689                 return NT_STATUS_INVALID_HANDLE;
5690         }
5691
5692         if (!lp_ea_support(SNUM(conn))) {
5693                 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
5694                         "EA's not supported.\n",
5695                         (unsigned int)total_data));
5696                 return NT_STATUS_EAS_NOT_SUPPORTED;
5697         }
5698
5699         if (total_data < 10) {
5700                 DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
5701                         "too small.\n",
5702                         (unsigned int)total_data));
5703                 return NT_STATUS_INVALID_PARAMETER;
5704         }
5705
5706         ea_list = read_nttrans_ea_list(talloc_tos(),
5707                                 pdata,
5708                                 total_data);
5709
5710         if (!ea_list) {
5711                 return NT_STATUS_INVALID_PARAMETER;
5712         }
5713         status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
5714
5715         DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
5716                 smb_fname_str_dbg(fsp->fsp_name),
5717                 nt_errstr(status) ));
5718
5719         return status;
5720 }
5721
5722
5723 /****************************************************************************
5724  Deal with SMB_SET_FILE_DISPOSITION_INFO.
5725 ****************************************************************************/
5726
5727 static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
5728                                 const char *pdata,
5729                                 int total_data,
5730                                 files_struct *fsp,
5731                                 struct smb_filename *smb_fname)
5732 {
5733         NTSTATUS status = NT_STATUS_OK;
5734         bool delete_on_close;
5735         uint32 dosmode = 0;
5736
5737         if (total_data < 1) {
5738                 return NT_STATUS_INVALID_PARAMETER;
5739         }
5740
5741         if (fsp == NULL) {
5742                 return NT_STATUS_INVALID_HANDLE;
5743         }
5744
5745         delete_on_close = (CVAL(pdata,0) ? True : False);
5746         dosmode = dos_mode(conn, smb_fname);
5747
5748         DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
5749                 "delete_on_close = %u\n",
5750                 smb_fname_str_dbg(smb_fname),
5751                 (unsigned int)dosmode,
5752                 (unsigned int)delete_on_close ));
5753
5754         if (delete_on_close) {
5755                 status = can_set_delete_on_close(fsp, dosmode);
5756                 if (!NT_STATUS_IS_OK(status)) {
5757                         return status;
5758                 }
5759         }
5760
5761         /* The set is across all open files on this dev/inode pair. */
5762         if (!set_delete_on_close(fsp, delete_on_close,
5763                                  &conn->server_info->utok)) {
5764                 return NT_STATUS_ACCESS_DENIED;
5765         }
5766         return NT_STATUS_OK;
5767 }
5768
5769 /****************************************************************************
5770  Deal with SMB_FILE_POSITION_INFORMATION.
5771 ****************************************************************************/
5772
5773 static NTSTATUS smb_file_position_information(connection_struct *conn,
5774                                 const char *pdata,
5775                                 int total_data,
5776                                 files_struct *fsp)
5777 {
5778         uint64_t position_information;
5779
5780         if (total_data < 8) {
5781                 return NT_STATUS_INVALID_PARAMETER;
5782         }
5783
5784         if (fsp == NULL) {
5785                 /* Ignore on pathname based set. */
5786                 return NT_STATUS_OK;
5787         }
5788
5789         position_information = (uint64_t)IVAL(pdata,0);
5790 #ifdef LARGE_SMB_OFF_T
5791         position_information |= (((uint64_t)IVAL(pdata,4)) << 32);
5792 #else /* LARGE_SMB_OFF_T */
5793         if (IVAL(pdata,4) != 0) {
5794                 /* more than 32 bits? */
5795                 return NT_STATUS_INVALID_PARAMETER;
5796         }
5797 #endif /* LARGE_SMB_OFF_T */
5798
5799         DEBUG(10,("smb_file_position_information: Set file position "
5800                   "information for file %s to %.0f\n", fsp_str_dbg(fsp),
5801                   (double)position_information));
5802         fsp->fh->position_information = position_information;
5803         return NT_STATUS_OK;
5804 }
5805
5806 /****************************************************************************
5807  Deal with SMB_FILE_MODE_INFORMATION.
5808 ****************************************************************************/
5809
5810 static NTSTATUS smb_file_mode_information(connection_struct *conn,
5811                                 const char *pdata,
5812                                 int total_data)
5813 {
5814         uint32 mode;
5815
5816         if (total_data < 4) {
5817                 return NT_STATUS_INVALID_PARAMETER;
5818         }
5819         mode = IVAL(pdata,0);
5820         if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
5821                 return NT_STATUS_INVALID_PARAMETER;
5822         }
5823         return NT_STATUS_OK;
5824 }
5825
5826 /****************************************************************************
5827  Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
5828 ****************************************************************************/
5829
5830 static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
5831                                        struct smb_request *req,
5832                                        const char *pdata,
5833                                        int total_data,
5834                                        const struct smb_filename *smb_fname)
5835 {
5836         char *link_target = NULL;
5837         const char *newname = smb_fname->base_name;
5838         TALLOC_CTX *ctx = talloc_tos();
5839
5840         /* Set a symbolic link. */
5841         /* Don't allow this if follow links is false. */
5842
5843         if (total_data == 0) {
5844                 return NT_STATUS_INVALID_PARAMETER;
5845         }
5846
5847         if (!lp_symlinks(SNUM(conn))) {
5848                 return NT_STATUS_ACCESS_DENIED;
5849         }
5850
5851         srvstr_pull_talloc(ctx, pdata, req->flags2, &link_target, pdata,
5852                     total_data, STR_TERMINATE);
5853
5854         if (!link_target) {
5855                 return NT_STATUS_INVALID_PARAMETER;
5856         }
5857
5858         DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
5859                         newname, link_target ));
5860
5861         if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0) {
5862                 return map_nt_error_from_unix(errno);
5863         }
5864
5865         return NT_STATUS_OK;
5866 }
5867
5868 /****************************************************************************
5869  Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
5870 ****************************************************************************/
5871
5872 static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
5873                                         struct smb_request *req,
5874                                         const char *pdata, int total_data,
5875                                         const struct smb_filename *smb_fname_new)
5876 {
5877         char *oldname = NULL;
5878         struct smb_filename *smb_fname_old = NULL;
5879         TALLOC_CTX *ctx = talloc_tos();
5880         NTSTATUS status = NT_STATUS_OK;
5881
5882         /* Set a hard link. */
5883         if (total_data == 0) {
5884                 return NT_STATUS_INVALID_PARAMETER;
5885         }
5886
5887         srvstr_get_path(ctx, pdata, req->flags2, &oldname, pdata,
5888                         total_data, STR_TERMINATE, &status);
5889         if (!NT_STATUS_IS_OK(status)) {
5890                 return status;
5891         }
5892
5893         DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
5894                 smb_fname_str_dbg(smb_fname_new), oldname));
5895
5896         status = filename_convert(ctx,
5897                                 conn,
5898                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
5899                                 oldname,
5900                                 0,
5901                                 NULL,
5902                                 &smb_fname_old);
5903         if (!NT_STATUS_IS_OK(status)) {
5904                 return status;
5905         }
5906
5907         return hardlink_internals(ctx, conn, smb_fname_old, smb_fname_new);
5908 }
5909
5910 /****************************************************************************
5911  Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
5912 ****************************************************************************/
5913
5914 static NTSTATUS smb2_file_rename_information(connection_struct *conn,
5915                                             struct smb_request *req,
5916                                             const char *pdata,
5917                                             int total_data,
5918                                             files_struct *fsp,
5919                                             struct smb_filename *smb_fname_src)
5920 {
5921         bool overwrite;
5922         uint32_t len;
5923         char *newname = NULL;
5924         struct smb_filename *smb_fname_dst = NULL;
5925         NTSTATUS status = NT_STATUS_OK;
5926         TALLOC_CTX *ctx = talloc_tos();
5927
5928         if (!fsp) {
5929                 return NT_STATUS_INVALID_HANDLE;
5930         }
5931
5932         if (total_data < 20) {
5933                 return NT_STATUS_INVALID_PARAMETER;
5934         }
5935
5936         overwrite = (CVAL(pdata,0) ? True : False);
5937         len = IVAL(pdata,16);
5938
5939         if (len > (total_data - 20) || (len == 0)) {
5940                 return NT_STATUS_INVALID_PARAMETER;
5941         }
5942
5943         srvstr_get_path(ctx, pdata, req->flags2, &newname,
5944                                 &pdata[20], len, STR_TERMINATE,
5945                                 &status);
5946         if (!NT_STATUS_IS_OK(status)) {
5947                 return status;
5948         }
5949
5950         DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
5951                                 newname));
5952
5953         status = filename_convert(ctx,
5954                                 conn,
5955                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
5956                                 newname,
5957                                 0,
5958                                 NULL,
5959                                 &smb_fname_dst);
5960         if (!NT_STATUS_IS_OK(status)) {
5961                 return status;
5962         }
5963
5964         /* Ok, this looks wrong to me, but appears to
5965          * be how SMB2 renames work. CHECK WITH Microsoft !
5966          * jra.
5967          */
5968         if (fsp->oplock_type != NO_OPLOCK) {
5969                 return NT_STATUS_SHARING_VIOLATION;
5970         }
5971
5972         if (fsp->base_fsp) {
5973                 /* newname must be a stream name. */
5974                 if (newname[0] != ':') {
5975                         return NT_STATUS_NOT_SUPPORTED;
5976                 }
5977
5978                 /* Create an smb_fname to call rename_internals_fsp() with. */
5979                 status = create_synthetic_smb_fname(talloc_tos(),
5980                     fsp->base_fsp->fsp_name->base_name, newname, NULL,
5981                     &smb_fname_dst);
5982                 if (!NT_STATUS_IS_OK(status)) {
5983                         goto out;
5984                 }
5985
5986                 /*
5987                  * Set the original last component, since
5988                  * rename_internals_fsp() requires it.
5989                  */
5990                 smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
5991                                                               newname);
5992                 if (smb_fname_dst->original_lcomp == NULL) {
5993                         status = NT_STATUS_NO_MEMORY;
5994                         goto out;
5995                 }
5996
5997         }
5998
5999         DEBUG(10,("smb2_file_rename_information: "
6000                   "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
6001                   fsp->fnum, fsp_str_dbg(fsp),
6002                   smb_fname_str_dbg(smb_fname_dst)));
6003         status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
6004                                       overwrite);
6005
6006  out:
6007         TALLOC_FREE(smb_fname_dst);
6008         return status;
6009 }
6010
6011
6012 /****************************************************************************
6013  Deal with SMB_FILE_RENAME_INFORMATION.
6014 ****************************************************************************/
6015
6016 static NTSTATUS smb_file_rename_information(connection_struct *conn,
6017                                             struct smb_request *req,
6018                                             const char *pdata,
6019                                             int total_data,
6020                                             files_struct *fsp,
6021                                             struct smb_filename *smb_fname_src)
6022 {
6023         bool overwrite;
6024         uint32 root_fid;
6025         uint32 len;
6026         char *newname = NULL;
6027         struct smb_filename *smb_fname_dst = NULL;
6028         bool dest_has_wcard = False;
6029         NTSTATUS status = NT_STATUS_OK;
6030         char *p;
6031         TALLOC_CTX *ctx = talloc_tos();
6032
6033         if (total_data < 13) {
6034                 return NT_STATUS_INVALID_PARAMETER;
6035         }
6036
6037         overwrite = (CVAL(pdata,0) ? True : False);
6038         root_fid = IVAL(pdata,4);
6039         len = IVAL(pdata,8);
6040
6041         if (len > (total_data - 12) || (len == 0) || (root_fid != 0)) {
6042                 return NT_STATUS_INVALID_PARAMETER;
6043         }
6044
6045         srvstr_get_path_wcard(ctx, pdata, req->flags2, &newname, &pdata[12],
6046                               len, 0, &status,
6047                               &dest_has_wcard);
6048         if (!NT_STATUS_IS_OK(status)) {
6049                 return status;
6050         }
6051
6052         DEBUG(10,("smb_file_rename_information: got name |%s|\n",
6053                                 newname));
6054
6055         status = resolve_dfspath_wcard(ctx, conn,
6056                                        req->flags2 & FLAGS2_DFS_PATHNAMES,
6057                                        newname,
6058                                        true,
6059                                        &newname,
6060                                        &dest_has_wcard);
6061         if (!NT_STATUS_IS_OK(status)) {
6062                 return status;
6063         }
6064
6065         /* Check the new name has no '/' characters. */
6066         if (strchr_m(newname, '/')) {
6067                 return NT_STATUS_NOT_SUPPORTED;
6068         }
6069
6070         if (fsp && fsp->base_fsp) {
6071                 /* newname must be a stream name. */
6072                 if (newname[0] != ':') {
6073                         return NT_STATUS_NOT_SUPPORTED;
6074                 }
6075
6076                 /* Create an smb_fname to call rename_internals_fsp() with. */
6077                 status = create_synthetic_smb_fname(talloc_tos(),
6078                     fsp->base_fsp->fsp_name->base_name, newname, NULL,
6079                     &smb_fname_dst);
6080                 if (!NT_STATUS_IS_OK(status)) {
6081                         goto out;
6082                 }
6083
6084                 /*
6085                  * Set the original last component, since
6086                  * rename_internals_fsp() requires it.
6087                  */
6088                 smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
6089                                                               newname);
6090                 if (smb_fname_dst->original_lcomp == NULL) {
6091                         status = NT_STATUS_NO_MEMORY;
6092                         goto out;
6093                 }
6094
6095         } else {
6096                 /*
6097                  * Build up an smb_fname_dst based on the filename passed in.
6098                  * We basically just strip off the last component, and put on
6099                  * the newname instead.
6100                  */
6101                 char *base_name = NULL;
6102
6103                 /* newname must *not* be a stream name. */
6104                 if (newname[0] == ':') {
6105                         return NT_STATUS_NOT_SUPPORTED;
6106                 }
6107
6108                 /*
6109                  * Strip off the last component (filename) of the path passed
6110                  * in.
6111                  */
6112                 base_name = talloc_strdup(ctx, smb_fname_src->base_name);
6113                 if (!base_name) {
6114                         return NT_STATUS_NO_MEMORY;
6115                 }
6116                 p = strrchr_m(base_name, '/');
6117                 if (p) {
6118                         p[1] = '\0';
6119                 } else {
6120                         base_name = talloc_strdup(ctx, "./");
6121                         if (!base_name) {
6122                                 return NT_STATUS_NO_MEMORY;
6123                         }
6124                 }
6125                 /* Append the new name. */
6126                 base_name = talloc_asprintf_append(base_name,
6127                                 "%s",
6128                                 newname);
6129                 if (!base_name) {
6130                         return NT_STATUS_NO_MEMORY;
6131                 }
6132
6133                 status = unix_convert(ctx, conn, base_name, &smb_fname_dst,
6134                                       (UCF_SAVE_LCOMP |
6135                                           (dest_has_wcard ?
6136                                               UCF_ALWAYS_ALLOW_WCARD_LCOMP :
6137                                               0)));
6138
6139                 /* If an error we expect this to be
6140                  * NT_STATUS_OBJECT_PATH_NOT_FOUND */
6141
6142                 if (!NT_STATUS_IS_OK(status)) {
6143                         if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND,
6144                                             status)) {
6145                                 goto out;
6146                         }
6147                         /* Create an smb_fname to call rename_internals_fsp() */
6148                         status = create_synthetic_smb_fname(ctx,
6149                                                             base_name, NULL,
6150                                                             NULL,
6151                                                             &smb_fname_dst);
6152                         if (!NT_STATUS_IS_OK(status)) {
6153                                 goto out;
6154                         }
6155                 }
6156         }
6157
6158         if (fsp) {
6159                 DEBUG(10,("smb_file_rename_information: "
6160                           "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
6161                           fsp->fnum, fsp_str_dbg(fsp),
6162                           smb_fname_str_dbg(smb_fname_dst)));
6163                 status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
6164                                               overwrite);
6165         } else {
6166                 DEBUG(10,("smb_file_rename_information: "
6167                           "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
6168                           smb_fname_str_dbg(smb_fname_src),
6169                           smb_fname_str_dbg(smb_fname_dst)));
6170                 status = rename_internals(ctx, conn, req, smb_fname_src,
6171                                           smb_fname_dst, 0, overwrite, false,
6172                                           dest_has_wcard,
6173                                           FILE_WRITE_ATTRIBUTES);
6174         }
6175  out:
6176         TALLOC_FREE(smb_fname_dst);
6177         return status;
6178 }
6179
6180 /****************************************************************************
6181  Deal with SMB_SET_POSIX_ACL.
6182 ****************************************************************************/
6183
6184 #if defined(HAVE_POSIX_ACLS)
6185 static NTSTATUS smb_set_posix_acl(connection_struct *conn,
6186                                 const char *pdata,
6187                                 int total_data,
6188                                 files_struct *fsp,
6189                                 const struct smb_filename *smb_fname)
6190 {
6191         uint16 posix_acl_version;
6192         uint16 num_file_acls;
6193         uint16 num_def_acls;
6194         bool valid_file_acls = True;
6195         bool valid_def_acls = True;
6196
6197         if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
6198                 return NT_STATUS_INVALID_PARAMETER;
6199         }
6200         posix_acl_version = SVAL(pdata,0);
6201         num_file_acls = SVAL(pdata,2);
6202         num_def_acls = SVAL(pdata,4);
6203
6204         if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
6205                 valid_file_acls = False;
6206                 num_file_acls = 0;
6207         }
6208
6209         if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
6210                 valid_def_acls = False;
6211                 num_def_acls = 0;
6212         }
6213
6214         if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
6215                 return NT_STATUS_INVALID_PARAMETER;
6216         }
6217
6218         if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
6219                         (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
6220                 return NT_STATUS_INVALID_PARAMETER;
6221         }
6222
6223         DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
6224                 smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp),
6225                 (unsigned int)num_file_acls,
6226                 (unsigned int)num_def_acls));
6227
6228         if (valid_file_acls && !set_unix_posix_acl(conn, fsp,
6229                 smb_fname->base_name, num_file_acls,
6230                 pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
6231                 return map_nt_error_from_unix(errno);
6232         }
6233
6234         if (valid_def_acls && !set_unix_posix_default_acl(conn,
6235                 smb_fname->base_name, &smb_fname->st, num_def_acls,
6236                 pdata + SMB_POSIX_ACL_HEADER_SIZE +
6237                 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
6238                 return map_nt_error_from_unix(errno);
6239         }
6240         return NT_STATUS_OK;
6241 }
6242 #endif
6243
6244 /****************************************************************************
6245  Deal with SMB_SET_POSIX_LOCK.
6246 ****************************************************************************/
6247
6248 static NTSTATUS smb_set_posix_lock(connection_struct *conn,
6249                                 struct smb_request *req,
6250                                 const char *pdata,
6251                                 int total_data,
6252                                 files_struct *fsp)
6253 {
6254         uint64_t count;
6255         uint64_t offset;
6256         uint64_t smblctx;
6257         bool blocking_lock = False;
6258         enum brl_type lock_type;
6259
6260         NTSTATUS status = NT_STATUS_OK;
6261
6262         if (fsp == NULL || fsp->fh->fd == -1) {
6263                 return NT_STATUS_INVALID_HANDLE;
6264         }
6265
6266         if (total_data != POSIX_LOCK_DATA_SIZE) {
6267                 return NT_STATUS_INVALID_PARAMETER;
6268         }
6269
6270         switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
6271                 case POSIX_LOCK_TYPE_READ:
6272                         lock_type = READ_LOCK;
6273                         break;
6274                 case POSIX_LOCK_TYPE_WRITE:
6275                         /* Return the right POSIX-mappable error code for files opened read-only. */
6276                         if (!fsp->can_write) {
6277                                 return NT_STATUS_INVALID_HANDLE;
6278                         }
6279                         lock_type = WRITE_LOCK;
6280                         break;
6281                 case POSIX_LOCK_TYPE_UNLOCK:
6282                         lock_type = UNLOCK_LOCK;
6283                         break;
6284                 default:
6285                         return NT_STATUS_INVALID_PARAMETER;
6286         }
6287
6288         if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_NOWAIT) {
6289                 blocking_lock = False;
6290         } else if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_WAIT) {
6291                 blocking_lock = True;
6292         } else {
6293                 return NT_STATUS_INVALID_PARAMETER;
6294         }
6295
6296         if (!lp_blocking_locks(SNUM(conn))) { 
6297                 blocking_lock = False;
6298         }
6299
6300         smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
6301 #if defined(HAVE_LONGLONG)
6302         offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
6303                         ((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
6304         count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
6305                         ((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
6306 #else /* HAVE_LONGLONG */
6307         offset = (uint64_t)IVAL(pdata,POSIX_LOCK_START_OFFSET);
6308         count = (uint64_t)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
6309 #endif /* HAVE_LONGLONG */
6310
6311         DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
6312                         "smblctx = %llu, count = %.0f, offset = %.0f\n",
6313                 fsp_str_dbg(fsp),
6314                 (unsigned int)lock_type,
6315                 (unsigned long long)smblctx,
6316                 (double)count,
6317                 (double)offset ));
6318
6319         if (lock_type == UNLOCK_LOCK) {
6320                 status = do_unlock(smbd_messaging_context(),
6321                                 fsp,
6322                                 smblctx,
6323                                 count,
6324                                 offset,
6325                                 POSIX_LOCK);
6326         } else {
6327                 uint64_t block_smblctx;
6328
6329                 struct byte_range_lock *br_lck = do_lock(smbd_messaging_context(),
6330                                                         fsp,
6331                                                         smblctx,
6332                                                         count,
6333                                                         offset,
6334                                                         lock_type,
6335                                                         POSIX_LOCK,
6336                                                         blocking_lock,
6337                                                         &status,
6338                                                         &block_smblctx,
6339                                                         NULL);
6340
6341                 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
6342                         /*
6343                          * A blocking lock was requested. Package up
6344                          * this smb into a queued request and push it
6345                          * onto the blocking lock queue.
6346                          */
6347                         if(push_blocking_lock_request(br_lck,
6348                                                 req,
6349                                                 fsp,
6350                                                 -1, /* infinite timeout. */
6351                                                 0,
6352                                                 smblctx,
6353                                                 lock_type,
6354                                                 POSIX_LOCK,
6355                                                 offset,
6356                                                 count,
6357                                                 block_smblctx)) {
6358                                 TALLOC_FREE(br_lck);
6359                                 return status;
6360                         }
6361                 }
6362                 TALLOC_FREE(br_lck);
6363         }
6364
6365         return status;
6366 }
6367
6368 /****************************************************************************
6369  Deal with SMB_SET_FILE_BASIC_INFO.
6370 ****************************************************************************/
6371
6372 static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
6373                                         const char *pdata,
6374                                         int total_data,
6375                                         files_struct *fsp,
6376                                         const struct smb_filename *smb_fname)
6377 {
6378         /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
6379         struct smb_file_time ft;
6380         uint32 dosmode = 0;
6381         NTSTATUS status = NT_STATUS_OK;
6382
6383         ZERO_STRUCT(ft);
6384
6385         if (total_data < 36) {
6386                 return NT_STATUS_INVALID_PARAMETER;
6387         }
6388
6389         /* Set the attributes */
6390         dosmode = IVAL(pdata,32);
6391         status = smb_set_file_dosmode(conn, smb_fname, dosmode);
6392         if (!NT_STATUS_IS_OK(status)) {
6393                 return status;
6394         }
6395
6396         /* create time */
6397         ft.create_time = interpret_long_date(pdata);
6398
6399         /* access time */
6400         ft.atime = interpret_long_date(pdata+8);
6401
6402         /* write time. */
6403         ft.mtime = interpret_long_date(pdata+16);
6404
6405         /* change time. */
6406         ft.ctime = interpret_long_date(pdata+24);
6407
6408         DEBUG(10, ("smb_set_file_basic_info: file %s\n",
6409                    smb_fname_str_dbg(smb_fname)));
6410
6411         return smb_set_file_time(conn, fsp, smb_fname, &ft,
6412                                  true);
6413 }
6414
6415 /****************************************************************************
6416  Deal with SMB_INFO_STANDARD.
6417 ****************************************************************************/
6418
6419 static NTSTATUS smb_set_info_standard(connection_struct *conn,
6420                                         const char *pdata,
6421                                         int total_data,
6422                                         files_struct *fsp,
6423                                         const struct smb_filename *smb_fname)
6424 {
6425         struct smb_file_time ft;
6426
6427         ZERO_STRUCT(ft);
6428
6429         if (total_data < 12) {
6430                 return NT_STATUS_INVALID_PARAMETER;
6431         }
6432
6433         /* create time */
6434         ft.create_time = convert_time_t_to_timespec(srv_make_unix_date2(pdata));
6435         /* access time */
6436         ft.atime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+4));
6437         /* write time */
6438         ft.mtime = convert_time_t_to_timespec(srv_make_unix_date2(pdata+8));
6439
6440         DEBUG(10,("smb_set_info_standard: file %s\n",
6441                 smb_fname_str_dbg(smb_fname)));
6442
6443         return smb_set_file_time(conn,
6444                                 fsp,
6445                                 smb_fname,
6446                                 &ft,
6447                                 true);
6448 }
6449
6450 /****************************************************************************
6451  Deal with SMB_SET_FILE_ALLOCATION_INFO.
6452 ****************************************************************************/
6453
6454 static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
6455                                              struct smb_request *req,
6456                                         const char *pdata,
6457                                         int total_data,
6458                                         files_struct *fsp,
6459                                         struct smb_filename *smb_fname)
6460 {
6461         uint64_t allocation_size = 0;
6462         NTSTATUS status = NT_STATUS_OK;
6463         files_struct *new_fsp = NULL;
6464
6465         if (!VALID_STAT(smb_fname->st)) {
6466                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6467         }
6468
6469         if (total_data < 8) {
6470                 return NT_STATUS_INVALID_PARAMETER;
6471         }
6472
6473         allocation_size = (uint64_t)IVAL(pdata,0);
6474 #ifdef LARGE_SMB_OFF_T
6475         allocation_size |= (((uint64_t)IVAL(pdata,4)) << 32);
6476 #else /* LARGE_SMB_OFF_T */
6477         if (IVAL(pdata,4) != 0) {
6478                 /* more than 32 bits? */
6479                 return NT_STATUS_INVALID_PARAMETER;
6480         }
6481 #endif /* LARGE_SMB_OFF_T */
6482
6483         DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
6484                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
6485                   (double)allocation_size));
6486
6487         if (allocation_size) {
6488                 allocation_size = smb_roundup(conn, allocation_size);
6489         }
6490
6491         DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
6492                   "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname),
6493                   (double)allocation_size));
6494
6495         if (fsp && fsp->fh->fd != -1) {
6496                 /* Open file handle. */
6497                 /* Only change if needed. */
6498                 if (allocation_size != get_file_size_stat(&smb_fname->st)) {
6499                         if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
6500                                 return map_nt_error_from_unix(errno);
6501                         }
6502                 }
6503                 /* But always update the time. */
6504                 /*
6505                  * This is equivalent to a write. Ensure it's seen immediately
6506                  * if there are no pending writes.
6507                  */
6508                 trigger_write_time_update_immediate(fsp);
6509                 return NT_STATUS_OK;
6510         }
6511
6512         /* Pathname or stat or directory file. */
6513         status = SMB_VFS_CREATE_FILE(
6514                 conn,                                   /* conn */
6515                 req,                                    /* req */
6516                 0,                                      /* root_dir_fid */
6517                 smb_fname,                              /* fname */
6518                 FILE_WRITE_DATA,                        /* access_mask */
6519                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
6520                     FILE_SHARE_DELETE),
6521                 FILE_OPEN,                              /* create_disposition*/
6522                 0,                                      /* create_options */
6523                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
6524                 FORCE_OPLOCK_BREAK_TO_NONE,             /* oplock_request */
6525                 0,                                      /* allocation_size */
6526                 0,                                      /* private_flags */
6527                 NULL,                                   /* sd */
6528                 NULL,                                   /* ea_list */
6529                 &new_fsp,                               /* result */
6530                 NULL);                                  /* pinfo */
6531
6532         if (!NT_STATUS_IS_OK(status)) {
6533                 /* NB. We check for open_was_deferred in the caller. */
6534                 return status;
6535         }
6536
6537         /* Only change if needed. */
6538         if (allocation_size != get_file_size_stat(&smb_fname->st)) {
6539                 if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
6540                         status = map_nt_error_from_unix(errno);
6541                         close_file(req, new_fsp, NORMAL_CLOSE);
6542                         return status;
6543                 }
6544         }
6545
6546         /* Changing the allocation size should set the last mod time. */
6547         /*
6548          * This is equivalent to a write. Ensure it's seen immediately
6549          * if there are no pending writes.
6550          */
6551         trigger_write_time_update_immediate(new_fsp);
6552
6553         close_file(req, new_fsp, NORMAL_CLOSE);
6554         return NT_STATUS_OK;
6555 }
6556
6557 /****************************************************************************
6558  Deal with SMB_SET_FILE_END_OF_FILE_INFO.
6559 ****************************************************************************/
6560
6561 static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
6562                                               struct smb_request *req,
6563                                         const char *pdata,
6564                                         int total_data,
6565                                         files_struct *fsp,
6566                                         const struct smb_filename *smb_fname,
6567                                         bool fail_after_createfile)
6568 {
6569         SMB_OFF_T size;
6570
6571         if (total_data < 8) {
6572                 return NT_STATUS_INVALID_PARAMETER;
6573         }
6574
6575         size = IVAL(pdata,0);
6576 #ifdef LARGE_SMB_OFF_T
6577         size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
6578 #else /* LARGE_SMB_OFF_T */
6579         if (IVAL(pdata,4) != 0) {
6580                 /* more than 32 bits? */
6581                 return NT_STATUS_INVALID_PARAMETER;
6582         }
6583 #endif /* LARGE_SMB_OFF_T */
6584         DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
6585                   "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
6586                   (double)size));
6587
6588         return smb_set_file_size(conn, req,
6589                                 fsp,
6590                                 smb_fname,
6591                                 &smb_fname->st,
6592                                 size,
6593                                 fail_after_createfile);
6594 }
6595
6596 /****************************************************************************
6597  Allow a UNIX info mknod.
6598 ****************************************************************************/
6599
6600 static NTSTATUS smb_unix_mknod(connection_struct *conn,
6601                                         const char *pdata,
6602                                         int total_data,
6603                                         const struct smb_filename *smb_fname)
6604 {
6605         uint32 file_type = IVAL(pdata,56);
6606 #if defined(HAVE_MAKEDEV)
6607         uint32 dev_major = IVAL(pdata,60);
6608         uint32 dev_minor = IVAL(pdata,68);
6609 #endif
6610         SMB_DEV_T dev = (SMB_DEV_T)0;
6611         uint32 raw_unixmode = IVAL(pdata,84);
6612         NTSTATUS status;
6613         mode_t unixmode;
6614
6615         if (total_data < 100) {
6616                 return NT_STATUS_INVALID_PARAMETER;
6617         }
6618
6619         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
6620                                       PERM_NEW_FILE, &unixmode);
6621         if (!NT_STATUS_IS_OK(status)) {
6622                 return status;
6623         }
6624
6625 #if defined(HAVE_MAKEDEV)
6626         dev = makedev(dev_major, dev_minor);
6627 #endif
6628
6629         switch (file_type) {
6630 #if defined(S_IFIFO)
6631                 case UNIX_TYPE_FIFO:
6632                         unixmode |= S_IFIFO;
6633                         break;
6634 #endif
6635 #if defined(S_IFSOCK)
6636                 case UNIX_TYPE_SOCKET:
6637                         unixmode |= S_IFSOCK;
6638                         break;
6639 #endif
6640 #if defined(S_IFCHR)
6641                 case UNIX_TYPE_CHARDEV:
6642                         unixmode |= S_IFCHR;
6643                         break;
6644 #endif
6645 #if defined(S_IFBLK)
6646                 case UNIX_TYPE_BLKDEV:
6647                         unixmode |= S_IFBLK;
6648                         break;
6649 #endif
6650                 default:
6651                         return NT_STATUS_INVALID_PARAMETER;
6652         }
6653
6654         DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
6655                   "%.0f mode 0%o for file %s\n", (double)dev,
6656                   (unsigned int)unixmode, smb_fname_str_dbg(smb_fname)));
6657
6658         /* Ok - do the mknod. */
6659         if (SMB_VFS_MKNOD(conn, smb_fname->base_name, unixmode, dev) != 0) {
6660                 return map_nt_error_from_unix(errno);
6661         }
6662
6663         /* If any of the other "set" calls fail we
6664          * don't want to end up with a half-constructed mknod.
6665          */
6666
6667         if (lp_inherit_perms(SNUM(conn))) {
6668                 char *parent;
6669                 if (!parent_dirname(talloc_tos(), smb_fname->base_name,
6670                                     &parent, NULL)) {
6671                         return NT_STATUS_NO_MEMORY;
6672                 }
6673                 inherit_access_posix_acl(conn, parent, smb_fname->base_name,
6674                                          unixmode);
6675                 TALLOC_FREE(parent);
6676         }
6677
6678         return NT_STATUS_OK;
6679 }
6680
6681 /****************************************************************************
6682  Deal with SMB_SET_FILE_UNIX_BASIC.
6683 ****************************************************************************/
6684
6685 static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
6686                                         struct smb_request *req,
6687                                         const char *pdata,
6688                                         int total_data,
6689                                         files_struct *fsp,
6690                                         const struct smb_filename *smb_fname)
6691 {
6692         struct smb_file_time ft;
6693         uint32 raw_unixmode;
6694         mode_t unixmode;
6695         SMB_OFF_T size = 0;
6696         uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
6697         gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
6698         NTSTATUS status = NT_STATUS_OK;
6699         bool delete_on_fail = False;
6700         enum perm_type ptype;
6701         files_struct *all_fsps = NULL;
6702         bool modify_mtime = true;
6703         struct file_id id;
6704         SMB_STRUCT_STAT sbuf;
6705
6706         ZERO_STRUCT(ft);
6707
6708         if (total_data < 100) {
6709                 return NT_STATUS_INVALID_PARAMETER;
6710         }
6711
6712         if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
6713            IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
6714                 size=IVAL(pdata,0); /* first 8 Bytes are size */
6715 #ifdef LARGE_SMB_OFF_T
6716                 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
6717 #else /* LARGE_SMB_OFF_T */
6718                 if (IVAL(pdata,4) != 0) {
6719                         /* more than 32 bits? */
6720                         return NT_STATUS_INVALID_PARAMETER;
6721                 }
6722 #endif /* LARGE_SMB_OFF_T */
6723         }
6724
6725         ft.atime = interpret_long_date(pdata+24); /* access_time */
6726         ft.mtime = interpret_long_date(pdata+32); /* modification_time */
6727         set_owner = (uid_t)IVAL(pdata,40);
6728         set_grp = (gid_t)IVAL(pdata,48);
6729         raw_unixmode = IVAL(pdata,84);
6730
6731         if (VALID_STAT(smb_fname->st)) {
6732                 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
6733                         ptype = PERM_EXISTING_DIR;
6734                 } else {
6735                         ptype = PERM_EXISTING_FILE;
6736                 }
6737         } else {
6738                 ptype = PERM_NEW_FILE;
6739         }
6740
6741         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
6742                                       ptype, &unixmode);
6743         if (!NT_STATUS_IS_OK(status)) {
6744                 return status;
6745         }
6746
6747         DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
6748                   "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
6749                   smb_fname_str_dbg(smb_fname), (double)size,
6750                   (unsigned int)set_owner, (unsigned int)set_grp,
6751                   (int)raw_unixmode));
6752
6753         sbuf = smb_fname->st;
6754
6755         if (!VALID_STAT(sbuf)) {
6756                 struct smb_filename *smb_fname_tmp = NULL;
6757                 /*
6758                  * The only valid use of this is to create character and block
6759                  * devices, and named pipes. This is deprecated (IMHO) and 
6760                  * a new info level should be used for mknod. JRA.
6761                  */
6762
6763                 status = smb_unix_mknod(conn,
6764                                         pdata,
6765                                         total_data,
6766                                         smb_fname);
6767                 if (!NT_STATUS_IS_OK(status)) {
6768                         return status;
6769                 }
6770
6771                 status = copy_smb_filename(talloc_tos(), smb_fname,
6772                                            &smb_fname_tmp);
6773                 if (!NT_STATUS_IS_OK(status)) {
6774                         return status;
6775                 }
6776
6777                 if (SMB_VFS_STAT(conn, smb_fname_tmp) != 0) {
6778                         status = map_nt_error_from_unix(errno);
6779                         TALLOC_FREE(smb_fname_tmp);
6780                         SMB_VFS_UNLINK(conn, smb_fname);
6781                         return status;
6782                 }
6783
6784                 sbuf = smb_fname_tmp->st;
6785                 TALLOC_FREE(smb_fname_tmp);
6786
6787                 /* Ensure we don't try and change anything else. */
6788                 raw_unixmode = SMB_MODE_NO_CHANGE;
6789                 size = get_file_size_stat(&sbuf);
6790                 ft.atime = sbuf.st_ex_atime;
6791                 ft.mtime = sbuf.st_ex_mtime;
6792                 /* 
6793                  * We continue here as we might want to change the 
6794                  * owner uid/gid.
6795                  */
6796                 delete_on_fail = True;
6797         }
6798
6799 #if 1
6800         /* Horrible backwards compatibility hack as an old server bug
6801          * allowed a CIFS client bug to remain unnoticed :-(. JRA.
6802          * */
6803
6804         if (!size) {
6805                 size = get_file_size_stat(&sbuf);
6806         }
6807 #endif
6808
6809         /*
6810          * Deal with the UNIX specific mode set.
6811          */
6812
6813         if (raw_unixmode != SMB_MODE_NO_CHANGE) {
6814                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
6815                           "setting mode 0%o for file %s\n",
6816                           (unsigned int)unixmode,
6817                           smb_fname_str_dbg(smb_fname)));
6818                 if (SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode) != 0) {
6819                         return map_nt_error_from_unix(errno);
6820                 }
6821         }
6822
6823         /*
6824          * Deal with the UNIX specific uid set.
6825          */
6826
6827         if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) &&
6828             (sbuf.st_ex_uid != set_owner)) {
6829                 int ret;
6830
6831                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
6832                           "changing owner %u for path %s\n",
6833                           (unsigned int)set_owner,
6834                           smb_fname_str_dbg(smb_fname)));
6835
6836                 if (S_ISLNK(sbuf.st_ex_mode)) {
6837                         ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name,
6838                                              set_owner, (gid_t)-1);
6839                 } else {
6840                         ret = SMB_VFS_CHOWN(conn, smb_fname->base_name,
6841                                             set_owner, (gid_t)-1);
6842                 }
6843
6844                 if (ret != 0) {
6845                         status = map_nt_error_from_unix(errno);
6846                         if (delete_on_fail) {
6847                                 SMB_VFS_UNLINK(conn, smb_fname);
6848                         }
6849                         return status;
6850                 }
6851         }
6852
6853         /*
6854          * Deal with the UNIX specific gid set.
6855          */
6856
6857         if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) &&
6858             (sbuf.st_ex_gid != set_grp)) {
6859                 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
6860                           "changing group %u for file %s\n",
6861                           (unsigned int)set_owner,
6862                           smb_fname_str_dbg(smb_fname)));
6863                 if (SMB_VFS_CHOWN(conn, smb_fname->base_name, (uid_t)-1,
6864                                   set_grp) != 0) {
6865                         status = map_nt_error_from_unix(errno);
6866                         if (delete_on_fail) {
6867                                 SMB_VFS_UNLINK(conn, smb_fname);
6868                         }
6869                         return status;
6870                 }
6871         }
6872
6873         /* Deal with any size changes. */
6874
6875         status = smb_set_file_size(conn, req,
6876                                    fsp,
6877                                    smb_fname,
6878                                    &sbuf,
6879                                    size,
6880                                    false);
6881         if (!NT_STATUS_IS_OK(status)) {
6882                 return status;
6883         }
6884
6885         /* Deal with any time changes. */
6886         if (null_timespec(ft.mtime) && null_timespec(ft.atime)) {
6887                 /* No change, don't cancel anything. */
6888                 return status;
6889         }
6890
6891         id = vfs_file_id_from_sbuf(conn, &sbuf);
6892         for(all_fsps = file_find_di_first(id); all_fsps;
6893                         all_fsps = file_find_di_next(all_fsps)) {
6894                 /*
6895                  * We're setting the time explicitly for UNIX.
6896                  * Cancel any pending changes over all handles.
6897                  */
6898                 all_fsps->update_write_time_on_close = false;
6899                 TALLOC_FREE(all_fsps->update_write_time_event);
6900         }
6901
6902         /*
6903          * Override the "setting_write_time"
6904          * parameter here as it almost does what
6905          * we need. Just remember if we modified
6906          * mtime and send the notify ourselves.
6907          */
6908         if (null_timespec(ft.mtime)) {
6909                 modify_mtime = false;
6910         }
6911
6912         status = smb_set_file_time(conn,
6913                                 fsp,
6914                                 smb_fname,
6915                                 &ft,
6916                                 false);
6917         if (modify_mtime) {
6918                 notify_fname(conn, NOTIFY_ACTION_MODIFIED,
6919                         FILE_NOTIFY_CHANGE_LAST_WRITE, smb_fname->base_name);
6920         }
6921         return status;
6922 }
6923
6924 /****************************************************************************
6925  Deal with SMB_SET_FILE_UNIX_INFO2.
6926 ****************************************************************************/
6927
6928 static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
6929                                         struct smb_request *req,
6930                                         const char *pdata,
6931                                         int total_data,
6932                                         files_struct *fsp,
6933                                         const struct smb_filename *smb_fname)
6934 {
6935         NTSTATUS status;
6936         uint32 smb_fflags;
6937         uint32 smb_fmask;
6938
6939         if (total_data < 116) {
6940                 return NT_STATUS_INVALID_PARAMETER;
6941         }
6942
6943         /* Start by setting all the fields that are common between UNIX_BASIC
6944          * and UNIX_INFO2.
6945          */
6946         status = smb_set_file_unix_basic(conn, req, pdata, total_data,
6947                                          fsp, smb_fname);
6948         if (!NT_STATUS_IS_OK(status)) {
6949                 return status;
6950         }
6951
6952         smb_fflags = IVAL(pdata, 108);
6953         smb_fmask = IVAL(pdata, 112);
6954
6955         /* NB: We should only attempt to alter the file flags if the client
6956          * sends a non-zero mask.
6957          */
6958         if (smb_fmask != 0) {
6959                 int stat_fflags = 0;
6960
6961                 if (!map_info2_flags_to_sbuf(&smb_fname->st, smb_fflags,
6962                                              smb_fmask, &stat_fflags)) {
6963                         /* Client asked to alter a flag we don't understand. */
6964                         return NT_STATUS_INVALID_PARAMETER;
6965                 }
6966
6967                 if (fsp && fsp->fh->fd != -1) {
6968                         /* XXX: we should be  using SMB_VFS_FCHFLAGS here. */
6969                         return NT_STATUS_NOT_SUPPORTED;
6970                 } else {
6971                         if (SMB_VFS_CHFLAGS(conn, smb_fname->base_name,
6972                                             stat_fflags) != 0) {
6973                                 return map_nt_error_from_unix(errno);
6974                         }
6975                 }
6976         }
6977
6978         /* XXX: need to add support for changing the create_time here. You
6979          * can do this for paths on Darwin with setattrlist(2). The right way
6980          * to hook this up is probably by extending the VFS utimes interface.
6981          */
6982
6983         return NT_STATUS_OK;
6984 }
6985
6986 /****************************************************************************
6987  Create a directory with POSIX semantics.
6988 ****************************************************************************/
6989
6990 static NTSTATUS smb_posix_mkdir(connection_struct *conn,
6991                                 struct smb_request *req,
6992                                 char **ppdata,
6993                                 int total_data,
6994                                 struct smb_filename *smb_fname,
6995                                 int *pdata_return_size)
6996 {
6997         NTSTATUS status = NT_STATUS_OK;
6998         uint32 raw_unixmode = 0;
6999         uint32 mod_unixmode = 0;
7000         mode_t unixmode = (mode_t)0;
7001         files_struct *fsp = NULL;
7002         uint16 info_level_return = 0;
7003         int info;
7004         char *pdata = *ppdata;
7005
7006         if (total_data < 18) {
7007                 return NT_STATUS_INVALID_PARAMETER;
7008         }
7009
7010         raw_unixmode = IVAL(pdata,8);
7011         /* Next 4 bytes are not yet defined. */
7012
7013         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
7014                                       PERM_NEW_DIR, &unixmode);
7015         if (!NT_STATUS_IS_OK(status)) {
7016                 return status;
7017         }
7018
7019         mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
7020
7021         DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
7022                   smb_fname_str_dbg(smb_fname), (unsigned int)unixmode));
7023
7024         status = SMB_VFS_CREATE_FILE(
7025                 conn,                                   /* conn */
7026                 req,                                    /* req */
7027                 0,                                      /* root_dir_fid */
7028                 smb_fname,                              /* fname */
7029                 FILE_READ_ATTRIBUTES,                   /* access_mask */
7030                 FILE_SHARE_NONE,                        /* share_access */
7031                 FILE_CREATE,                            /* create_disposition*/
7032                 FILE_DIRECTORY_FILE,                    /* create_options */
7033                 mod_unixmode,                           /* file_attributes */
7034                 0,                                      /* oplock_request */
7035                 0,                                      /* allocation_size */
7036                 0,                                      /* private_flags */
7037                 NULL,                                   /* sd */
7038                 NULL,                                   /* ea_list */
7039                 &fsp,                                   /* result */
7040                 &info);                                 /* pinfo */
7041
7042         if (NT_STATUS_IS_OK(status)) {
7043                 close_file(req, fsp, NORMAL_CLOSE);
7044         }
7045
7046         info_level_return = SVAL(pdata,16);
7047  
7048         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
7049                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
7050         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
7051                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
7052         } else {
7053                 *pdata_return_size = 12;
7054         }
7055
7056         /* Realloc the data size */
7057         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
7058         if (*ppdata == NULL) {
7059                 *pdata_return_size = 0;
7060                 return NT_STATUS_NO_MEMORY;
7061         }
7062         pdata = *ppdata;
7063
7064         SSVAL(pdata,0,NO_OPLOCK_RETURN);
7065         SSVAL(pdata,2,0); /* No fnum. */
7066         SIVAL(pdata,4,info); /* Was directory created. */
7067
7068         switch (info_level_return) {
7069                 case SMB_QUERY_FILE_UNIX_BASIC:
7070                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
7071                         SSVAL(pdata,10,0); /* Padding. */
7072                         store_file_unix_basic(conn, pdata + 12, fsp,
7073                                               &smb_fname->st);
7074                         break;
7075                 case SMB_QUERY_FILE_UNIX_INFO2:
7076                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
7077                         SSVAL(pdata,10,0); /* Padding. */
7078                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
7079                                                     &smb_fname->st);
7080                         break;
7081                 default:
7082                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
7083                         SSVAL(pdata,10,0); /* Padding. */
7084                         break;
7085         }
7086
7087         return status;
7088 }
7089
7090 /****************************************************************************
7091  Open/Create a file with POSIX semantics.
7092 ****************************************************************************/
7093
7094 static NTSTATUS smb_posix_open(connection_struct *conn,
7095                                struct smb_request *req,
7096                                 char **ppdata,
7097                                 int total_data,
7098                                 struct smb_filename *smb_fname,
7099                                 int *pdata_return_size)
7100 {
7101         bool extended_oplock_granted = False;
7102         char *pdata = *ppdata;
7103         uint32 flags = 0;
7104         uint32 wire_open_mode = 0;
7105         uint32 raw_unixmode = 0;
7106         uint32 mod_unixmode = 0;
7107         uint32 create_disp = 0;
7108         uint32 access_mask = 0;
7109         uint32 create_options = 0;
7110         NTSTATUS status = NT_STATUS_OK;
7111         mode_t unixmode = (mode_t)0;
7112         files_struct *fsp = NULL;
7113         int oplock_request = 0;
7114         int info = 0;
7115         uint16 info_level_return = 0;
7116
7117         if (total_data < 18) {
7118                 return NT_STATUS_INVALID_PARAMETER;
7119         }
7120
7121         flags = IVAL(pdata,0);
7122         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
7123         if (oplock_request) {
7124                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
7125         }
7126
7127         wire_open_mode = IVAL(pdata,4);
7128
7129         if (wire_open_mode == (SMB_O_CREAT|SMB_O_DIRECTORY)) {
7130                 return smb_posix_mkdir(conn, req,
7131                                         ppdata,
7132                                         total_data,
7133                                         smb_fname,
7134                                         pdata_return_size);
7135         }
7136
7137         switch (wire_open_mode & SMB_ACCMODE) {
7138                 case SMB_O_RDONLY:
7139                         access_mask = FILE_READ_DATA;
7140                         break;
7141                 case SMB_O_WRONLY:
7142                         access_mask = FILE_WRITE_DATA;
7143                         break;
7144                 case SMB_O_RDWR:
7145                         access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
7146                         break;
7147                 default:
7148                         DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
7149                                 (unsigned int)wire_open_mode ));
7150                         return NT_STATUS_INVALID_PARAMETER;
7151         }
7152
7153         wire_open_mode &= ~SMB_ACCMODE;
7154
7155         if((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) == (SMB_O_CREAT | SMB_O_EXCL)) {
7156                 create_disp = FILE_CREATE;
7157         } else if((wire_open_mode & (SMB_O_CREAT | SMB_O_TRUNC)) == (SMB_O_CREAT | SMB_O_TRUNC)) {
7158                 create_disp = FILE_OVERWRITE_IF;
7159         } else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) {
7160                 create_disp = FILE_OPEN_IF;
7161         } else if ((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL | SMB_O_TRUNC)) == 0) {
7162                 create_disp = FILE_OPEN;
7163         } else {
7164                 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
7165                         (unsigned int)wire_open_mode ));
7166                 return NT_STATUS_INVALID_PARAMETER;
7167         }
7168
7169         raw_unixmode = IVAL(pdata,8);
7170         /* Next 4 bytes are not yet defined. */
7171
7172         status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
7173                                       (VALID_STAT(smb_fname->st) ?
7174                                           PERM_EXISTING_FILE : PERM_NEW_FILE),
7175                                       &unixmode);
7176
7177         if (!NT_STATUS_IS_OK(status)) {
7178                 return status;
7179         }
7180
7181         mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
7182
7183         if (wire_open_mode & SMB_O_SYNC) {
7184                 create_options |= FILE_WRITE_THROUGH;
7185         }
7186         if (wire_open_mode & SMB_O_APPEND) {
7187                 access_mask |= FILE_APPEND_DATA;
7188         }
7189         if (wire_open_mode & SMB_O_DIRECT) {
7190                 mod_unixmode |= FILE_FLAG_NO_BUFFERING;
7191         }
7192
7193         DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
7194                 smb_fname_str_dbg(smb_fname),
7195                 (unsigned int)wire_open_mode,
7196                 (unsigned int)unixmode ));
7197
7198         status = SMB_VFS_CREATE_FILE(
7199                 conn,                                   /* conn */
7200                 req,                                    /* req */
7201                 0,                                      /* root_dir_fid */
7202                 smb_fname,                              /* fname */
7203                 access_mask,                            /* access_mask */
7204                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
7205                     FILE_SHARE_DELETE),
7206                 create_disp,                            /* create_disposition*/
7207                 FILE_NON_DIRECTORY_FILE,                /* create_options */
7208                 mod_unixmode,                           /* file_attributes */
7209                 oplock_request,                         /* oplock_request */
7210                 0,                                      /* allocation_size */
7211                 0,                                      /* private_flags */
7212                 NULL,                                   /* sd */
7213                 NULL,                                   /* ea_list */
7214                 &fsp,                                   /* result */
7215                 &info);                                 /* pinfo */
7216
7217         if (!NT_STATUS_IS_OK(status)) {
7218                 return status;
7219         }
7220
7221         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
7222                 extended_oplock_granted = True;
7223         }
7224
7225         if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
7226                 extended_oplock_granted = True;
7227         }
7228
7229         info_level_return = SVAL(pdata,16);
7230  
7231         /* Allocate the correct return size. */
7232
7233         if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
7234                 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
7235         } else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
7236                 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
7237         } else {
7238                 *pdata_return_size = 12;
7239         }
7240
7241         /* Realloc the data size */
7242         *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
7243         if (*ppdata == NULL) {
7244                 close_file(req, fsp, ERROR_CLOSE);
7245                 *pdata_return_size = 0;
7246                 return NT_STATUS_NO_MEMORY;
7247         }
7248         pdata = *ppdata;
7249
7250         if (extended_oplock_granted) {
7251                 if (flags & REQUEST_BATCH_OPLOCK) {
7252                         SSVAL(pdata,0, BATCH_OPLOCK_RETURN);
7253                 } else {
7254                         SSVAL(pdata,0, EXCLUSIVE_OPLOCK_RETURN);
7255                 }
7256         } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
7257                 SSVAL(pdata,0, LEVEL_II_OPLOCK_RETURN);
7258         } else {
7259                 SSVAL(pdata,0,NO_OPLOCK_RETURN);
7260         }
7261
7262         SSVAL(pdata,2,fsp->fnum);
7263         SIVAL(pdata,4,info); /* Was file created etc. */
7264
7265         switch (info_level_return) {
7266                 case SMB_QUERY_FILE_UNIX_BASIC:
7267                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
7268                         SSVAL(pdata,10,0); /* padding. */
7269                         store_file_unix_basic(conn, pdata + 12, fsp,
7270                                               &smb_fname->st);
7271                         break;
7272                 case SMB_QUERY_FILE_UNIX_INFO2:
7273                         SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
7274                         SSVAL(pdata,10,0); /* padding. */
7275                         store_file_unix_basic_info2(conn, pdata + 12, fsp,
7276                                                     &smb_fname->st);
7277                         break;
7278                 default:
7279                         SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
7280                         SSVAL(pdata,10,0); /* padding. */
7281                         break;
7282         }
7283         return NT_STATUS_OK;
7284 }
7285
7286 /****************************************************************************
7287  Delete a file with POSIX semantics.
7288 ****************************************************************************/
7289
7290 static NTSTATUS smb_posix_unlink(connection_struct *conn,
7291                                  struct smb_request *req,
7292                                 const char *pdata,
7293                                 int total_data,
7294                                 struct smb_filename *smb_fname)
7295 {
7296         NTSTATUS status = NT_STATUS_OK;
7297         files_struct *fsp = NULL;
7298         uint16 flags = 0;
7299         char del = 1;
7300         int info = 0;
7301         int create_options = 0;
7302         int i;
7303         struct share_mode_lock *lck = NULL;
7304
7305         if (total_data < 2) {
7306                 return NT_STATUS_INVALID_PARAMETER;
7307         }
7308
7309         flags = SVAL(pdata,0);
7310
7311         if (!VALID_STAT(smb_fname->st)) {
7312                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
7313         }
7314
7315         if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
7316                         !VALID_STAT_OF_DIR(smb_fname->st)) {
7317                 return NT_STATUS_NOT_A_DIRECTORY;
7318         }
7319
7320         DEBUG(10,("smb_posix_unlink: %s %s\n",
7321                 (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
7322                 smb_fname_str_dbg(smb_fname)));
7323
7324         if (VALID_STAT_OF_DIR(smb_fname->st)) {
7325                 create_options |= FILE_DIRECTORY_FILE;
7326         }
7327
7328         status = SMB_VFS_CREATE_FILE(
7329                 conn,                                   /* conn */
7330                 req,                                    /* req */
7331                 0,                                      /* root_dir_fid */
7332                 smb_fname,                              /* fname */
7333                 DELETE_ACCESS,                          /* access_mask */
7334                 (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
7335                     FILE_SHARE_DELETE),
7336                 FILE_OPEN,                              /* create_disposition*/
7337                 create_options,                         /* create_options */
7338                 FILE_FLAG_POSIX_SEMANTICS|0777,         /* file_attributes */
7339                 0,                                      /* oplock_request */
7340                 0,                                      /* allocation_size */
7341                 0,                                      /* private_flags */
7342                 NULL,                                   /* sd */
7343                 NULL,                                   /* ea_list */
7344                 &fsp,                                   /* result */
7345                 &info);                                 /* pinfo */
7346
7347         if (!NT_STATUS_IS_OK(status)) {
7348                 return status;
7349         }
7350
7351         /*
7352          * Don't lie to client. If we can't really delete due to
7353          * non-POSIX opens return SHARING_VIOLATION.
7354          */
7355
7356         lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
7357                                   NULL);
7358         if (lck == NULL) {
7359                 DEBUG(0, ("smb_posix_unlink: Could not get share mode "
7360                           "lock for file %s\n", fsp_str_dbg(fsp)));
7361                 close_file(req, fsp, NORMAL_CLOSE);
7362                 return NT_STATUS_INVALID_PARAMETER;
7363         }
7364
7365         /*
7366          * See if others still have the file open. If this is the case, then
7367          * don't delete. If all opens are POSIX delete we can set the delete
7368          * on close disposition.
7369          */
7370         for (i=0; i<lck->num_share_modes; i++) {
7371                 struct share_mode_entry *e = &lck->share_modes[i];
7372                 if (is_valid_share_mode_entry(e)) {
7373                         if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
7374                                 continue;
7375                         }
7376                         /* Fail with sharing violation. */
7377                         close_file(req, fsp, NORMAL_CLOSE);
7378                         TALLOC_FREE(lck);
7379                         return NT_STATUS_SHARING_VIOLATION;
7380                 }
7381         }
7382
7383         /*
7384          * Set the delete on close.
7385          */
7386         status = smb_set_file_disposition_info(conn,
7387                                                 &del,
7388                                                 1,
7389                                                 fsp,
7390                                                 smb_fname);
7391
7392         if (!NT_STATUS_IS_OK(status)) {
7393                 close_file(req, fsp, NORMAL_CLOSE);
7394                 TALLOC_FREE(lck);
7395                 return status;
7396         }
7397         TALLOC_FREE(lck);
7398         return close_file(req, fsp, NORMAL_CLOSE);
7399 }
7400
7401 NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
7402                                 struct smb_request *req,
7403                                 TALLOC_CTX *mem_ctx,
7404                                 uint16_t info_level,
7405                                 files_struct *fsp,
7406                                 struct smb_filename *smb_fname,
7407                                 char **ppdata, int total_data,
7408                                 int *ret_data_size)
7409 {
7410         char *pdata = *ppdata;
7411         NTSTATUS status = NT_STATUS_OK;
7412         int data_return_size = 0;
7413
7414         *ret_data_size = 0;
7415
7416         if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
7417                 return NT_STATUS_INVALID_LEVEL;
7418         }
7419
7420         if (!CAN_WRITE(conn)) {
7421                 /* Allow POSIX opens. The open path will deny
7422                  * any non-readonly opens. */
7423                 if (info_level != SMB_POSIX_PATH_OPEN) {
7424                         return NT_STATUS_DOS(ERRSRV, ERRaccess);
7425                 }
7426         }
7427
7428         DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d "
7429                  "totdata=%d\n", smb_fname_str_dbg(smb_fname),
7430                  fsp ? fsp->fnum : -1, info_level, total_data));
7431
7432         switch (info_level) {
7433
7434                 case SMB_INFO_STANDARD:
7435                 {
7436                         status = smb_set_info_standard(conn,
7437                                         pdata,
7438                                         total_data,
7439                                         fsp,
7440                                         smb_fname);
7441                         break;
7442                 }
7443
7444                 case SMB_INFO_SET_EA:
7445                 {
7446                         status = smb_info_set_ea(conn,
7447                                                 pdata,
7448                                                 total_data,
7449                                                 fsp,
7450                                                 smb_fname);
7451                         break;
7452                 }
7453
7454                 case SMB_SET_FILE_BASIC_INFO:
7455                 case SMB_FILE_BASIC_INFORMATION:
7456                 {
7457                         status = smb_set_file_basic_info(conn,
7458                                                         pdata,
7459                                                         total_data,
7460                                                         fsp,
7461                                                         smb_fname);
7462                         break;
7463                 }
7464
7465                 case SMB_FILE_ALLOCATION_INFORMATION:
7466                 case SMB_SET_FILE_ALLOCATION_INFO:
7467                 {
7468                         status = smb_set_file_allocation_info(conn, req,
7469                                                                 pdata,
7470                                                                 total_data,
7471                                                                 fsp,
7472                                                                 smb_fname);
7473                         break;
7474                 }
7475
7476                 case SMB_FILE_END_OF_FILE_INFORMATION:
7477                 case SMB_SET_FILE_END_OF_FILE_INFO:
7478                 {
7479                         /*
7480                          * XP/Win7 both fail after the createfile with
7481                          * SMB_SET_FILE_END_OF_FILE_INFO but not
7482                          * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
7483                          * The level is known here, so pass it down
7484                          * appropriately.
7485                          */
7486                         bool should_fail =
7487                             (info_level == SMB_SET_FILE_END_OF_FILE_INFO);
7488
7489                         status = smb_set_file_end_of_file_info(conn, req,
7490                                                                 pdata,
7491                                                                 total_data,
7492                                                                 fsp,
7493                                                                 smb_fname,
7494                                                                 should_fail);
7495                         break;
7496                 }
7497
7498                 case SMB_FILE_DISPOSITION_INFORMATION:
7499                 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
7500                 {
7501 #if 0
7502                         /* JRA - We used to just ignore this on a path ? 
7503                          * Shouldn't this be invalid level on a pathname
7504                          * based call ?
7505                          */
7506                         if (tran_call != TRANSACT2_SETFILEINFO) {
7507                                 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
7508                         }
7509 #endif
7510                         status = smb_set_file_disposition_info(conn,
7511                                                 pdata,
7512                                                 total_data,
7513                                                 fsp,
7514                                                 smb_fname);
7515                         break;
7516                 }
7517
7518                 case SMB_FILE_POSITION_INFORMATION:
7519                 {
7520                         status = smb_file_position_information(conn,
7521                                                 pdata,
7522                                                 total_data,
7523                                                 fsp);
7524                         break;
7525                 }
7526
7527                 case SMB_FILE_FULL_EA_INFORMATION:
7528                 {
7529                         status = smb_set_file_full_ea_info(conn,
7530                                                 pdata,
7531                                                 total_data,
7532                                                 fsp);
7533                         break;
7534                 }
7535
7536                 /* From tridge Samba4 : 
7537                  * MODE_INFORMATION in setfileinfo (I have no
7538                  * idea what "mode information" on a file is - it takes a value of 0,
7539                  * 2, 4 or 6. What could it be?).
7540                  */
7541
7542                 case SMB_FILE_MODE_INFORMATION:
7543                 {
7544                         status = smb_file_mode_information(conn,
7545                                                 pdata,
7546                                                 total_data);
7547                         break;
7548                 }
7549
7550                 /*
7551                  * CIFS UNIX extensions.
7552                  */
7553
7554                 case SMB_SET_FILE_UNIX_BASIC:
7555                 {
7556                         status = smb_set_file_unix_basic(conn, req,
7557                                                         pdata,
7558                                                         total_data,
7559                                                         fsp,
7560                                                         smb_fname);
7561                         break;
7562                 }
7563
7564                 case SMB_SET_FILE_UNIX_INFO2:
7565                 {
7566                         status = smb_set_file_unix_info2(conn, req,
7567                                                         pdata,
7568                                                         total_data,
7569                                                         fsp,
7570                                                         smb_fname);
7571                         break;
7572                 }
7573
7574                 case SMB_SET_FILE_UNIX_LINK:
7575                 {
7576                         if (fsp) {
7577                                 /* We must have a pathname for this. */
7578                                 return NT_STATUS_INVALID_LEVEL;
7579                         }
7580                         status = smb_set_file_unix_link(conn, req, pdata,
7581                                                         total_data, smb_fname);
7582                         break;
7583                 }
7584
7585                 case SMB_SET_FILE_UNIX_HLINK:
7586                 {
7587                         if (fsp) {
7588                                 /* We must have a pathname for this. */
7589                                 return NT_STATUS_INVALID_LEVEL;
7590                         }
7591                         status = smb_set_file_unix_hlink(conn, req,
7592                                                          pdata, total_data,
7593                                                          smb_fname);
7594                         break;
7595                 }
7596
7597                 case SMB_FILE_RENAME_INFORMATION:
7598                 {
7599                         status = smb_file_rename_information(conn, req,
7600                                                              pdata, total_data,
7601                                                              fsp, smb_fname);
7602                         break;
7603                 }
7604
7605                 case SMB2_FILE_RENAME_INFORMATION_INTERNAL:
7606                 {
7607                         /* SMB2 rename information. */
7608                         status = smb2_file_rename_information(conn, req,
7609                                                              pdata, total_data,
7610                                                              fsp, smb_fname);
7611                         break;
7612                 }
7613
7614 #if defined(HAVE_POSIX_ACLS)
7615                 case SMB_SET_POSIX_ACL:
7616                 {
7617                         status = smb_set_posix_acl(conn,
7618                                                 pdata,
7619                                                 total_data,
7620                                                 fsp,
7621                                                 smb_fname);
7622                         break;
7623                 }
7624 #endif
7625
7626                 case SMB_SET_POSIX_LOCK:
7627                 {
7628                         if (!fsp) {
7629                                 return NT_STATUS_INVALID_LEVEL;
7630                         }
7631                         status = smb_set_posix_lock(conn, req,
7632                                                     pdata, total_data, fsp);
7633                         break;
7634                 }
7635
7636                 case SMB_POSIX_PATH_OPEN:
7637                 {
7638                         if (fsp) {
7639                                 /* We must have a pathname for this. */
7640                                 return NT_STATUS_INVALID_LEVEL;
7641                         }
7642
7643                         status = smb_posix_open(conn, req,
7644                                                 ppdata,
7645                                                 total_data,
7646                                                 smb_fname,
7647                                                 &data_return_size);
7648                         break;
7649                 }
7650
7651                 case SMB_POSIX_PATH_UNLINK:
7652                 {
7653                         if (fsp) {
7654                                 /* We must have a pathname for this. */
7655                                 return NT_STATUS_INVALID_LEVEL;
7656                         }
7657
7658                         status = smb_posix_unlink(conn, req,
7659                                                 pdata,
7660                                                 total_data,
7661                                                 smb_fname);
7662                         break;
7663                 }
7664
7665                 default:
7666                         return NT_STATUS_INVALID_LEVEL;
7667         }
7668
7669         if (!NT_STATUS_IS_OK(status)) {
7670                 return status;
7671         }
7672
7673         *ret_data_size = data_return_size;
7674         return NT_STATUS_OK;
7675 }
7676
7677 /****************************************************************************
7678  Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
7679 ****************************************************************************/
7680
7681 static void call_trans2setfilepathinfo(connection_struct *conn,
7682                                        struct smb_request *req,
7683                                        unsigned int tran_call,
7684                                        char **pparams, int total_params,
7685                                        char **ppdata, int total_data,
7686                                        unsigned int max_data_bytes)
7687 {
7688         char *params = *pparams;
7689         char *pdata = *ppdata;
7690         uint16 info_level;
7691         struct smb_filename *smb_fname = NULL;
7692         files_struct *fsp = NULL;
7693         NTSTATUS status = NT_STATUS_OK;
7694         int data_return_size = 0;
7695
7696         if (!params) {
7697                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7698                 return;
7699         }
7700
7701         if (tran_call == TRANSACT2_SETFILEINFO) {
7702                 if (total_params < 4) {
7703                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7704                         return;
7705                 }
7706
7707                 fsp = file_fsp(req, SVAL(params,0));
7708                 /* Basic check for non-null fsp. */
7709                 if (!check_fsp_open(conn, req, fsp)) {
7710                         return;
7711                 }
7712                 info_level = SVAL(params,2);
7713
7714                 status = copy_smb_filename(talloc_tos(), fsp->fsp_name,
7715                                            &smb_fname);
7716                 if (!NT_STATUS_IS_OK(status)) {
7717                         reply_nterror(req, status);
7718                         return;
7719                 }
7720
7721                 if(fsp->is_directory || fsp->fh->fd == -1) {
7722                         /*
7723                          * This is actually a SETFILEINFO on a directory
7724                          * handle (returned from an NT SMB). NT5.0 seems
7725                          * to do this call. JRA.
7726                          */
7727                         if (INFO_LEVEL_IS_UNIX(info_level)) {
7728                                 /* Always do lstat for UNIX calls. */
7729                                 if (SMB_VFS_LSTAT(conn, smb_fname)) {
7730                                         DEBUG(3,("call_trans2setfilepathinfo: "
7731                                                  "SMB_VFS_LSTAT of %s failed "
7732                                                  "(%s)\n",
7733                                                  smb_fname_str_dbg(smb_fname),
7734                                                  strerror(errno)));
7735                                         reply_nterror(req, map_nt_error_from_unix(errno));
7736                                         return;
7737                                 }
7738                         } else {
7739                                 if (SMB_VFS_STAT(conn, smb_fname) != 0) {
7740                                         DEBUG(3,("call_trans2setfilepathinfo: "
7741                                                  "fileinfo of %s failed (%s)\n",
7742                                                  smb_fname_str_dbg(smb_fname),
7743                                                  strerror(errno)));
7744                                         reply_nterror(req, map_nt_error_from_unix(errno));
7745                                         return;
7746                                 }
7747                         }
7748                 } else if (fsp->print_file) {
7749                         /*
7750                          * Doing a DELETE_ON_CLOSE should cancel a print job.
7751                          */
7752                         if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
7753                                 fsp->fh->private_options |= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE;
7754
7755                                 DEBUG(3,("call_trans2setfilepathinfo: "
7756                                          "Cancelling print job (%s)\n",
7757                                          fsp_str_dbg(fsp)));
7758
7759                                 SSVAL(params,0,0);
7760                                 send_trans2_replies(conn, req, params, 2,
7761                                                     *ppdata, 0,
7762                                                     max_data_bytes);
7763                                 return;
7764                         } else {
7765                                 reply_nterror(req,
7766                                         NT_STATUS_OBJECT_PATH_NOT_FOUND);
7767                                 return;
7768                         }
7769                 } else {
7770                         /*
7771                          * Original code - this is an open file.
7772                          */
7773                         if (!check_fsp(conn, req, fsp)) {
7774                                 return;
7775                         }
7776
7777                         if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
7778                                 DEBUG(3,("call_trans2setfilepathinfo: fstat "
7779                                          "of fnum %d failed (%s)\n", fsp->fnum,
7780                                          strerror(errno)));
7781                                 reply_nterror(req, map_nt_error_from_unix(errno));
7782                                 return;
7783                         }
7784                 }
7785         } else {
7786                 char *fname = NULL;
7787
7788                 /* set path info */
7789                 if (total_params < 7) {
7790                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7791                         return;
7792                 }
7793
7794                 info_level = SVAL(params,0);
7795                 srvstr_get_path(req, params, req->flags2, &fname, &params[6],
7796                                 total_params - 6, STR_TERMINATE,
7797                                 &status);
7798                 if (!NT_STATUS_IS_OK(status)) {
7799                         reply_nterror(req, status);
7800                         return;
7801                 }
7802
7803                 status = filename_convert(req, conn,
7804                                          req->flags2 & FLAGS2_DFS_PATHNAMES,
7805                                          fname,
7806                                          0,
7807                                          NULL,
7808                                          &smb_fname);
7809                 if (!NT_STATUS_IS_OK(status)) {
7810                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
7811                                 reply_botherror(req,
7812                                                 NT_STATUS_PATH_NOT_COVERED,
7813                                                 ERRSRV, ERRbadpath);
7814                                 return;
7815                         }
7816                         reply_nterror(req, status);
7817                         return;
7818                 }
7819
7820                 if (INFO_LEVEL_IS_UNIX(info_level)) {
7821                         /*
7822                          * For CIFS UNIX extensions the target name may not exist.
7823                          */
7824
7825                         /* Always do lstat for UNIX calls. */
7826                         SMB_VFS_LSTAT(conn, smb_fname);
7827
7828                 } else if (!VALID_STAT(smb_fname->st) &&
7829                            SMB_VFS_STAT(conn, smb_fname)) {
7830                         DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
7831                                  "%s failed (%s)\n",
7832                                  smb_fname_str_dbg(smb_fname),
7833                                  strerror(errno)));
7834                         reply_nterror(req, map_nt_error_from_unix(errno));
7835                         return;
7836                 }
7837         }
7838
7839         DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d "
7840                  "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
7841                  fsp ? fsp->fnum : -1, info_level,total_data));
7842
7843         /* Realloc the parameter size */
7844         *pparams = (char *)SMB_REALLOC(*pparams,2);
7845         if (*pparams == NULL) {
7846                 reply_nterror(req, NT_STATUS_NO_MEMORY);
7847                 return;
7848         }
7849         params = *pparams;
7850
7851         SSVAL(params,0,0);
7852
7853         status = smbd_do_setfilepathinfo(conn, req, req,
7854                                          info_level,
7855                                          fsp,
7856                                          smb_fname,
7857                                          ppdata, total_data,
7858                                          &data_return_size);
7859         if (!NT_STATUS_IS_OK(status)) {
7860                 if (open_was_deferred(req->mid)) {
7861                         /* We have re-scheduled this call. */
7862                         return;
7863                 }
7864                 if (blocking_lock_was_deferred_smb1(req->mid)) {
7865                         /* We have re-scheduled this call. */
7866                         return;
7867                 }
7868                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
7869                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
7870                                         ERRSRV, ERRbadpath);
7871                         return;
7872                 }
7873                 if (info_level == SMB_POSIX_PATH_OPEN) {
7874                         reply_openerror(req, status);
7875                         return;
7876                 }
7877
7878                 reply_nterror(req, status);
7879                 return;
7880         }
7881
7882         send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
7883                             max_data_bytes);
7884
7885         return;
7886 }
7887
7888 /****************************************************************************
7889  Reply to a TRANS2_MKDIR (make directory with extended attributes).
7890 ****************************************************************************/
7891
7892 static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
7893                              char **pparams, int total_params,
7894                              char **ppdata, int total_data,
7895                              unsigned int max_data_bytes)
7896 {
7897         struct smb_filename *smb_dname = NULL;
7898         char *params = *pparams;
7899         char *pdata = *ppdata;
7900         char *directory = NULL;
7901         NTSTATUS status = NT_STATUS_OK;
7902         struct ea_list *ea_list = NULL;
7903         TALLOC_CTX *ctx = talloc_tos();
7904
7905         if (!CAN_WRITE(conn)) {
7906                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
7907                 return;
7908         }
7909
7910         if (total_params < 5) {
7911                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7912                 return;
7913         }
7914
7915         srvstr_get_path(ctx, params, req->flags2, &directory, &params[4],
7916                         total_params - 4, STR_TERMINATE,
7917                         &status);
7918         if (!NT_STATUS_IS_OK(status)) {
7919                 reply_nterror(req, status);
7920                 return;
7921         }
7922
7923         DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
7924
7925         status = filename_convert(ctx,
7926                                 conn,
7927                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
7928                                 directory,
7929                                 0,
7930                                 NULL,
7931                                 &smb_dname);
7932
7933         if (!NT_STATUS_IS_OK(status)) {
7934                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
7935                         reply_botherror(req,
7936                                 NT_STATUS_PATH_NOT_COVERED,
7937                                 ERRSRV, ERRbadpath);
7938                         return;
7939                 }
7940                 reply_nterror(req, status);
7941                 return;
7942         }
7943
7944         /*
7945          * OS/2 workplace shell seems to send SET_EA requests of "null"
7946          * length (4 bytes containing IVAL 4).
7947          * They seem to have no effect. Bug #3212. JRA.
7948          */
7949
7950         if (total_data && (total_data != 4)) {
7951                 /* Any data in this call is an EA list. */
7952                 if (total_data < 10) {
7953                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7954                         goto out;
7955                 }
7956
7957                 if (IVAL(pdata,0) > total_data) {
7958                         DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
7959                                 IVAL(pdata,0), (unsigned int)total_data));
7960                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7961                         goto out;
7962                 }
7963
7964                 ea_list = read_ea_list(talloc_tos(), pdata + 4,
7965                                        total_data - 4);
7966                 if (!ea_list) {
7967                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
7968                         goto out;
7969                 }
7970
7971                 if (!lp_ea_support(SNUM(conn))) {
7972                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
7973                         goto out;
7974                 }
7975         }
7976         /* If total_data == 4 Windows doesn't care what values
7977          * are placed in that field, it just ignores them.
7978          * The System i QNTC IBM SMB client puts bad values here,
7979          * so ignore them. */
7980
7981         status = create_directory(conn, req, smb_dname);
7982
7983         if (!NT_STATUS_IS_OK(status)) {
7984                 reply_nterror(req, status);
7985                 goto out;
7986         }
7987
7988         /* Try and set any given EA. */
7989         if (ea_list) {
7990                 status = set_ea(conn, NULL, smb_dname, ea_list);
7991                 if (!NT_STATUS_IS_OK(status)) {
7992                         reply_nterror(req, status);
7993                         goto out;
7994                 }
7995         }
7996
7997         /* Realloc the parameter and data sizes */
7998         *pparams = (char *)SMB_REALLOC(*pparams,2);
7999         if(*pparams == NULL) {
8000                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8001                 goto out;
8002         }
8003         params = *pparams;
8004
8005         SSVAL(params,0,0);
8006
8007         send_trans2_replies(conn, req, params, 2, *ppdata, 0, max_data_bytes);
8008
8009  out:
8010         TALLOC_FREE(smb_dname);
8011         return;
8012 }
8013
8014 /****************************************************************************
8015  Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
8016  We don't actually do this - we just send a null response.
8017 ****************************************************************************/
8018
8019 static void call_trans2findnotifyfirst(connection_struct *conn,
8020                                        struct smb_request *req,
8021                                        char **pparams, int total_params,
8022                                        char **ppdata, int total_data,
8023                                        unsigned int max_data_bytes)
8024 {
8025         char *params = *pparams;
8026         uint16 info_level;
8027
8028         if (total_params < 6) {
8029                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8030                 return;
8031         }
8032
8033         info_level = SVAL(params,4);
8034         DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
8035
8036         switch (info_level) {
8037                 case 1:
8038                 case 2:
8039                         break;
8040                 default:
8041                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
8042                         return;
8043         }
8044
8045         /* Realloc the parameter and data sizes */
8046         *pparams = (char *)SMB_REALLOC(*pparams,6);
8047         if (*pparams == NULL) {
8048                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8049                 return;
8050         }
8051         params = *pparams;
8052
8053         SSVAL(params,0,fnf_handle);
8054         SSVAL(params,2,0); /* No changes */
8055         SSVAL(params,4,0); /* No EA errors */
8056
8057         fnf_handle++;
8058
8059         if(fnf_handle == 0)
8060                 fnf_handle = 257;
8061
8062         send_trans2_replies(conn, req, params, 6, *ppdata, 0, max_data_bytes);
8063
8064         return;
8065 }
8066
8067 /****************************************************************************
8068  Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for 
8069  changes). Currently this does nothing.
8070 ****************************************************************************/
8071
8072 static void call_trans2findnotifynext(connection_struct *conn,
8073                                       struct smb_request *req,
8074                                       char **pparams, int total_params,
8075                                       char **ppdata, int total_data,
8076                                       unsigned int max_data_bytes)
8077 {
8078         char *params = *pparams;
8079
8080         DEBUG(3,("call_trans2findnotifynext\n"));
8081
8082         /* Realloc the parameter and data sizes */
8083         *pparams = (char *)SMB_REALLOC(*pparams,4);
8084         if (*pparams == NULL) {
8085                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8086                 return;
8087         }
8088         params = *pparams;
8089
8090         SSVAL(params,0,0); /* No changes */
8091         SSVAL(params,2,0); /* No EA errors */
8092
8093         send_trans2_replies(conn, req, params, 4, *ppdata, 0, max_data_bytes);
8094
8095         return;
8096 }
8097
8098 /****************************************************************************
8099  Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
8100 ****************************************************************************/
8101
8102 static void call_trans2getdfsreferral(connection_struct *conn,
8103                                       struct smb_request *req,
8104                                       char **pparams, int total_params,
8105                                       char **ppdata, int total_data,
8106                                       unsigned int max_data_bytes)
8107 {
8108         char *params = *pparams;
8109         char *pathname = NULL;
8110         int reply_size = 0;
8111         int max_referral_level;
8112         NTSTATUS status = NT_STATUS_OK;
8113         TALLOC_CTX *ctx = talloc_tos();
8114
8115         DEBUG(10,("call_trans2getdfsreferral\n"));
8116
8117         if (total_params < 3) {
8118                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8119                 return;
8120         }
8121
8122         max_referral_level = SVAL(params,0);
8123
8124         if(!lp_host_msdfs()) {
8125                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
8126                 return;
8127         }
8128
8129         srvstr_pull_talloc(ctx, params, req->flags2, &pathname, &params[2],
8130                     total_params - 2, STR_TERMINATE);
8131         if (!pathname) {
8132                 reply_nterror(req, NT_STATUS_NOT_FOUND);
8133                 return;
8134         }
8135         if((reply_size = setup_dfs_referral(conn, pathname, max_referral_level,
8136                                             ppdata,&status)) < 0) {
8137                 reply_nterror(req, status);
8138                 return;
8139         }
8140
8141         SSVAL(req->inbuf, smb_flg2,
8142               SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
8143         send_trans2_replies(conn, req,0,0,*ppdata,reply_size, max_data_bytes);
8144
8145         return;
8146 }
8147
8148 #define LMCAT_SPL       0x53
8149 #define LMFUNC_GETJOBID 0x60
8150
8151 /****************************************************************************
8152  Reply to a TRANS2_IOCTL - used for OS/2 printing.
8153 ****************************************************************************/
8154
8155 static void call_trans2ioctl(connection_struct *conn,
8156                              struct smb_request *req,
8157                              char **pparams, int total_params,
8158                              char **ppdata, int total_data,
8159                              unsigned int max_data_bytes)
8160 {
8161         char *pdata = *ppdata;
8162         files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0));
8163
8164         /* check for an invalid fid before proceeding */
8165
8166         if (!fsp) {
8167                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
8168                 return;
8169         }
8170
8171         if ((SVAL(req->vwv+16, 0) == LMCAT_SPL)
8172             && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
8173                 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
8174                 if (*ppdata == NULL) {
8175                         reply_nterror(req, NT_STATUS_NO_MEMORY);
8176                         return;
8177                 }
8178                 pdata = *ppdata;
8179
8180                 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
8181                         CAN ACCEPT THIS IN UNICODE. JRA. */
8182
8183                 /* Job number */
8184                 if (fsp->print_file) {
8185                         SSVAL(pdata, 0, fsp->print_file->rap_jobid);
8186                 } else {
8187                         SSVAL(pdata, 0, 0);
8188                 }
8189                 srvstr_push(pdata, req->flags2, pdata + 2,
8190                             global_myname(), 15,
8191                             STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
8192                 srvstr_push(pdata, req->flags2, pdata+18,
8193                             lp_servicename(SNUM(conn)), 13,
8194                             STR_ASCII|STR_TERMINATE); /* Service name */
8195                 send_trans2_replies(conn, req, *pparams, 0, *ppdata, 32,
8196                                     max_data_bytes);
8197                 return;
8198         }
8199
8200         DEBUG(2,("Unknown TRANS2_IOCTL\n"));
8201         reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
8202 }
8203
8204 /****************************************************************************
8205  Reply to a SMBfindclose (stop trans2 directory search).
8206 ****************************************************************************/
8207
8208 void reply_findclose(struct smb_request *req)
8209 {
8210         int dptr_num;
8211         struct smbd_server_connection *sconn = smbd_server_conn;
8212
8213         START_PROFILE(SMBfindclose);
8214
8215         if (req->wct < 1) {
8216                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8217                 END_PROFILE(SMBfindclose);
8218                 return;
8219         }
8220
8221         dptr_num = SVALS(req->vwv+0, 0);
8222
8223         DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
8224
8225         dptr_close(sconn, &dptr_num);
8226
8227         reply_outbuf(req, 0, 0);
8228
8229         DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
8230
8231         END_PROFILE(SMBfindclose);
8232         return;
8233 }
8234
8235 /****************************************************************************
8236  Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
8237 ****************************************************************************/
8238
8239 void reply_findnclose(struct smb_request *req)
8240 {
8241         int dptr_num;
8242
8243         START_PROFILE(SMBfindnclose);
8244
8245         if (req->wct < 1) {
8246                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8247                 END_PROFILE(SMBfindnclose);
8248                 return;
8249         }
8250
8251         dptr_num = SVAL(req->vwv+0, 0);
8252
8253         DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
8254
8255         /* We never give out valid handles for a 
8256            findnotifyfirst - so any dptr_num is ok here. 
8257            Just ignore it. */
8258
8259         reply_outbuf(req, 0, 0);
8260
8261         DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
8262
8263         END_PROFILE(SMBfindnclose);
8264         return;
8265 }
8266
8267 static void handle_trans2(connection_struct *conn, struct smb_request *req,
8268                           struct trans_state *state)
8269 {
8270         if (get_Protocol() >= PROTOCOL_NT1) {
8271                 req->flags2 |= 0x40; /* IS_LONG_NAME */
8272                 SSVAL(req->inbuf,smb_flg2,req->flags2);
8273         }
8274
8275         if (conn->encrypt_level == Required && !req->encrypted) {
8276                 if (state->call != TRANSACT2_QFSINFO &&
8277                                 state->call != TRANSACT2_SETFSINFO) {
8278                         DEBUG(0,("handle_trans2: encryption required "
8279                                 "with call 0x%x\n",
8280                                 (unsigned int)state->call));
8281                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
8282                         return;
8283                 }
8284         }
8285
8286         SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
8287
8288         /* Now we must call the relevant TRANS2 function */
8289         switch(state->call)  {
8290         case TRANSACT2_OPEN:
8291         {
8292                 START_PROFILE(Trans2_open);
8293                 call_trans2open(conn, req,
8294                                 &state->param, state->total_param,
8295                                 &state->data, state->total_data,
8296                                 state->max_data_return);
8297                 END_PROFILE(Trans2_open);
8298                 break;
8299         }
8300
8301         case TRANSACT2_FINDFIRST:
8302         {
8303                 START_PROFILE(Trans2_findfirst);
8304                 call_trans2findfirst(conn, req,
8305                                      &state->param, state->total_param,
8306                                      &state->data, state->total_data,
8307                                      state->max_data_return);
8308                 END_PROFILE(Trans2_findfirst);
8309                 break;
8310         }
8311
8312         case TRANSACT2_FINDNEXT:
8313         {
8314                 START_PROFILE(Trans2_findnext);
8315                 call_trans2findnext(conn, req,
8316                                     &state->param, state->total_param,
8317                                     &state->data, state->total_data,
8318                                     state->max_data_return);
8319                 END_PROFILE(Trans2_findnext);
8320                 break;
8321         }
8322
8323         case TRANSACT2_QFSINFO:
8324         {
8325                 START_PROFILE(Trans2_qfsinfo);
8326                 call_trans2qfsinfo(conn, req,
8327                                    &state->param, state->total_param,
8328                                    &state->data, state->total_data,
8329                                    state->max_data_return);
8330                 END_PROFILE(Trans2_qfsinfo);
8331             break;
8332         }
8333
8334         case TRANSACT2_SETFSINFO:
8335         {
8336                 START_PROFILE(Trans2_setfsinfo);
8337                 call_trans2setfsinfo(conn, req,
8338                                      &state->param, state->total_param,
8339                                      &state->data, state->total_data,
8340                                      state->max_data_return);
8341                 END_PROFILE(Trans2_setfsinfo);
8342                 break;
8343         }
8344
8345         case TRANSACT2_QPATHINFO:
8346         case TRANSACT2_QFILEINFO:
8347         {
8348                 START_PROFILE(Trans2_qpathinfo);
8349                 call_trans2qfilepathinfo(conn, req, state->call,
8350                                          &state->param, state->total_param,
8351                                          &state->data, state->total_data,
8352                                          state->max_data_return);
8353                 END_PROFILE(Trans2_qpathinfo);
8354                 break;
8355         }
8356
8357         case TRANSACT2_SETPATHINFO:
8358         case TRANSACT2_SETFILEINFO:
8359         {
8360                 START_PROFILE(Trans2_setpathinfo);
8361                 call_trans2setfilepathinfo(conn, req, state->call,
8362                                            &state->param, state->total_param,
8363                                            &state->data, state->total_data,
8364                                            state->max_data_return);
8365                 END_PROFILE(Trans2_setpathinfo);
8366                 break;
8367         }
8368
8369         case TRANSACT2_FINDNOTIFYFIRST:
8370         {
8371                 START_PROFILE(Trans2_findnotifyfirst);
8372                 call_trans2findnotifyfirst(conn, req,
8373                                            &state->param, state->total_param,
8374                                            &state->data, state->total_data,
8375                                            state->max_data_return);
8376                 END_PROFILE(Trans2_findnotifyfirst);
8377                 break;
8378         }
8379
8380         case TRANSACT2_FINDNOTIFYNEXT:
8381         {
8382                 START_PROFILE(Trans2_findnotifynext);
8383                 call_trans2findnotifynext(conn, req,
8384                                           &state->param, state->total_param,
8385                                           &state->data, state->total_data,
8386                                           state->max_data_return);
8387                 END_PROFILE(Trans2_findnotifynext);
8388                 break;
8389         }
8390
8391         case TRANSACT2_MKDIR:
8392         {
8393                 START_PROFILE(Trans2_mkdir);
8394                 call_trans2mkdir(conn, req,
8395                                  &state->param, state->total_param,
8396                                  &state->data, state->total_data,
8397                                  state->max_data_return);
8398                 END_PROFILE(Trans2_mkdir);
8399                 break;
8400         }
8401
8402         case TRANSACT2_GET_DFS_REFERRAL:
8403         {
8404                 START_PROFILE(Trans2_get_dfs_referral);
8405                 call_trans2getdfsreferral(conn, req,
8406                                           &state->param, state->total_param,
8407                                           &state->data, state->total_data,
8408                                           state->max_data_return);
8409                 END_PROFILE(Trans2_get_dfs_referral);
8410                 break;
8411         }
8412
8413         case TRANSACT2_IOCTL:
8414         {
8415                 START_PROFILE(Trans2_ioctl);
8416                 call_trans2ioctl(conn, req,
8417                                  &state->param, state->total_param,
8418                                  &state->data, state->total_data,
8419                                  state->max_data_return);
8420                 END_PROFILE(Trans2_ioctl);
8421                 break;
8422         }
8423
8424         default:
8425                 /* Error in request */
8426                 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
8427                 reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
8428         }
8429 }
8430
8431 /****************************************************************************
8432  Reply to a SMBtrans2.
8433  ****************************************************************************/
8434
8435 void reply_trans2(struct smb_request *req)
8436 {
8437         connection_struct *conn = req->conn;
8438         unsigned int dsoff;
8439         unsigned int dscnt;
8440         unsigned int psoff;
8441         unsigned int pscnt;
8442         unsigned int tran_call;
8443         struct trans_state *state;
8444         NTSTATUS result;
8445
8446         START_PROFILE(SMBtrans2);
8447
8448         if (req->wct < 14) {
8449                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8450                 END_PROFILE(SMBtrans2);
8451                 return;
8452         }
8453
8454         dsoff = SVAL(req->vwv+12, 0);
8455         dscnt = SVAL(req->vwv+11, 0);
8456         psoff = SVAL(req->vwv+10, 0);
8457         pscnt = SVAL(req->vwv+9, 0);
8458         tran_call = SVAL(req->vwv+14, 0);
8459
8460         result = allow_new_trans(conn->pending_trans, req->mid);
8461         if (!NT_STATUS_IS_OK(result)) {
8462                 DEBUG(2, ("Got invalid trans2 request: %s\n",
8463                           nt_errstr(result)));
8464                 reply_nterror(req, result);
8465                 END_PROFILE(SMBtrans2);
8466                 return;
8467         }
8468
8469         if (IS_IPC(conn)) {
8470                 switch (tran_call) {
8471                 /* List the allowed trans2 calls on IPC$ */
8472                 case TRANSACT2_OPEN:
8473                 case TRANSACT2_GET_DFS_REFERRAL:
8474                 case TRANSACT2_QFILEINFO:
8475                 case TRANSACT2_QFSINFO:
8476                 case TRANSACT2_SETFSINFO:
8477                         break;
8478                 default:
8479                         reply_nterror(req, NT_STATUS_ACCESS_DENIED);
8480                         END_PROFILE(SMBtrans2);
8481                         return;
8482                 }
8483         }
8484
8485         if ((state = TALLOC_P(conn, struct trans_state)) == NULL) {
8486                 DEBUG(0, ("talloc failed\n"));
8487                 reply_nterror(req, NT_STATUS_NO_MEMORY);
8488                 END_PROFILE(SMBtrans2);
8489                 return;
8490         }
8491
8492         state->cmd = SMBtrans2;
8493
8494         state->mid = req->mid;
8495         state->vuid = req->vuid;
8496         state->setup_count = SVAL(req->vwv+13, 0);
8497         state->setup = NULL;
8498         state->total_param = SVAL(req->vwv+0, 0);
8499         state->param = NULL;
8500         state->total_data =  SVAL(req->vwv+1, 0);
8501         state->data = NULL;
8502         state->max_param_return = SVAL(req->vwv+2, 0);
8503         state->max_data_return  = SVAL(req->vwv+3, 0);
8504         state->max_setup_return = SVAL(req->vwv+4, 0);
8505         state->close_on_completion = BITSETW(req->vwv+5, 0);
8506         state->one_way = BITSETW(req->vwv+5, 1);
8507
8508         state->call = tran_call;
8509
8510         /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
8511            is so as a sanity check */
8512         if (state->setup_count != 1) {
8513                 /*
8514                  * Need to have rc=0 for ioctl to get job id for OS/2.
8515                  *  Network printing will fail if function is not successful.
8516                  *  Similar function in reply.c will be used if protocol
8517                  *  is LANMAN1.0 instead of LM1.2X002.
8518                  *  Until DosPrintSetJobInfo with PRJINFO3 is supported,
8519                  *  outbuf doesn't have to be set(only job id is used).
8520                  */
8521                 if ( (state->setup_count == 4)
8522                      && (tran_call == TRANSACT2_IOCTL)
8523                      && (SVAL(req->vwv+16, 0) == LMCAT_SPL)
8524                      && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
8525                         DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
8526                 } else {
8527                         DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
8528                         DEBUG(2,("Transaction is %d\n",tran_call));
8529                         TALLOC_FREE(state);
8530                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8531                         END_PROFILE(SMBtrans2);
8532                         return;
8533                 }
8534         }
8535
8536         if ((dscnt > state->total_data) || (pscnt > state->total_param))
8537                 goto bad_param;
8538
8539         if (state->total_data) {
8540
8541                 if (trans_oob(state->total_data, 0, dscnt)
8542                     || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
8543                         goto bad_param;
8544                 }
8545
8546                 /* Can't use talloc here, the core routines do realloc on the
8547                  * params and data. */
8548                 state->data = (char *)SMB_MALLOC(state->total_data);
8549                 if (state->data == NULL) {
8550                         DEBUG(0,("reply_trans2: data malloc fail for %u "
8551                                  "bytes !\n", (unsigned int)state->total_data));
8552                         TALLOC_FREE(state);
8553                         reply_nterror(req, NT_STATUS_NO_MEMORY);
8554                         END_PROFILE(SMBtrans2);
8555                         return;
8556                 }
8557
8558                 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
8559         }
8560
8561         if (state->total_param) {
8562
8563                 if (trans_oob(state->total_param, 0, pscnt)
8564                     || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
8565                         goto bad_param;
8566                 }
8567
8568                 /* Can't use talloc here, the core routines do realloc on the
8569                  * params and data. */
8570                 state->param = (char *)SMB_MALLOC(state->total_param);
8571                 if (state->param == NULL) {
8572                         DEBUG(0,("reply_trans: param malloc fail for %u "
8573                                  "bytes !\n", (unsigned int)state->total_param));
8574                         SAFE_FREE(state->data);
8575                         TALLOC_FREE(state);
8576                         reply_nterror(req, NT_STATUS_NO_MEMORY);
8577                         END_PROFILE(SMBtrans2);
8578                         return;
8579                 } 
8580
8581                 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
8582         }
8583
8584         state->received_data  = dscnt;
8585         state->received_param = pscnt;
8586
8587         if ((state->received_param == state->total_param) &&
8588             (state->received_data == state->total_data)) {
8589
8590                 handle_trans2(conn, req, state);
8591
8592                 SAFE_FREE(state->data);
8593                 SAFE_FREE(state->param);
8594                 TALLOC_FREE(state);
8595                 END_PROFILE(SMBtrans2);
8596                 return;
8597         }
8598
8599         DLIST_ADD(conn->pending_trans, state);
8600
8601         /* We need to send an interim response then receive the rest
8602            of the parameter/data bytes */
8603         reply_outbuf(req, 0, 0);
8604         show_msg((char *)req->outbuf);
8605         END_PROFILE(SMBtrans2);
8606         return;
8607
8608   bad_param:
8609
8610         DEBUG(0,("reply_trans2: invalid trans parameters\n"));
8611         SAFE_FREE(state->data);
8612         SAFE_FREE(state->param);
8613         TALLOC_FREE(state);
8614         END_PROFILE(SMBtrans2);
8615         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8616 }
8617
8618
8619 /****************************************************************************
8620  Reply to a SMBtranss2
8621  ****************************************************************************/
8622
8623 void reply_transs2(struct smb_request *req)
8624 {
8625         connection_struct *conn = req->conn;
8626         unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
8627         struct trans_state *state;
8628
8629         START_PROFILE(SMBtranss2);
8630
8631         show_msg((char *)req->inbuf);
8632
8633         if (req->wct < 8) {
8634                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8635                 END_PROFILE(SMBtranss2);
8636                 return;
8637         }
8638
8639         for (state = conn->pending_trans; state != NULL;
8640              state = state->next) {
8641                 if (state->mid == req->mid) {
8642                         break;
8643                 }
8644         }
8645
8646         if ((state == NULL) || (state->cmd != SMBtrans2)) {
8647                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8648                 END_PROFILE(SMBtranss2);
8649                 return;
8650         }
8651
8652         /* Revise state->total_param and state->total_data in case they have
8653            changed downwards */
8654
8655         if (SVAL(req->vwv+0, 0) < state->total_param)
8656                 state->total_param = SVAL(req->vwv+0, 0);
8657         if (SVAL(req->vwv+1, 0) < state->total_data)
8658                 state->total_data = SVAL(req->vwv+1, 0);
8659
8660         pcnt = SVAL(req->vwv+2, 0);
8661         poff = SVAL(req->vwv+3, 0);
8662         pdisp = SVAL(req->vwv+4, 0);
8663
8664         dcnt = SVAL(req->vwv+5, 0);
8665         doff = SVAL(req->vwv+6, 0);
8666         ddisp = SVAL(req->vwv+7, 0);
8667
8668         state->received_param += pcnt;
8669         state->received_data += dcnt;
8670
8671         if ((state->received_data > state->total_data) ||
8672             (state->received_param > state->total_param))
8673                 goto bad_param;
8674
8675         if (pcnt) {
8676                 if (trans_oob(state->total_param, pdisp, pcnt)
8677                     || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
8678                         goto bad_param;
8679                 }
8680                 memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
8681         }
8682
8683         if (dcnt) {
8684                 if (trans_oob(state->total_data, ddisp, dcnt)
8685                     || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
8686                         goto bad_param;
8687                 }
8688                 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
8689         }
8690
8691         if ((state->received_param < state->total_param) ||
8692             (state->received_data < state->total_data)) {
8693                 END_PROFILE(SMBtranss2);
8694                 return;
8695         }
8696
8697         handle_trans2(conn, req, state);
8698
8699         DLIST_REMOVE(conn->pending_trans, state);
8700         SAFE_FREE(state->data);
8701         SAFE_FREE(state->param);
8702         TALLOC_FREE(state);
8703
8704         END_PROFILE(SMBtranss2);
8705         return;
8706
8707   bad_param:
8708
8709         DEBUG(0,("reply_transs2: invalid trans parameters\n"));
8710         DLIST_REMOVE(conn->pending_trans, state);
8711         SAFE_FREE(state->data);
8712         SAFE_FREE(state->param);
8713         TALLOC_FREE(state);
8714         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
8715         END_PROFILE(SMBtranss2);
8716         return;
8717 }