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