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