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