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