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