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