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