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