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