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