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