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