s3-talloc Change TALLOC_ARRAY() to talloc_array()
[samba.git] / source3 / smbd / reply.c
1 /*
2    Unix SMB/CIFS implementation.
3    Main SMB reply routines
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Andrew Bartlett      2001
6    Copyright (C) Jeremy Allison 1992-2007.
7    Copyright (C) Volker Lendecke 2007
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22 /*
23    This file handles most of the reply_ calls that the server
24    makes to handle specific protocols
25 */
26
27 #include "includes.h"
28 #include "system/filesys.h"
29 #include "printing.h"
30 #include "smbd/smbd.h"
31 #include "smbd/globals.h"
32 #include "fake_file.h"
33 #include "rpc_client/rpc_client.h"
34 #include "../librpc/gen_ndr/ndr_spoolss_c.h"
35 #include "rpc_client/cli_spoolss.h"
36 #include "rpc_client/init_spoolss.h"
37 #include "rpc_server/rpc_ncacn_np.h"
38 #include "libcli/security/security.h"
39 #include "libsmb/nmblib.h"
40 #include "auth.h"
41 #include "smbprofile.h"
42
43 /****************************************************************************
44  Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
45  path or anything including wildcards.
46  We're assuming here that '/' is not the second byte in any multibyte char
47  set (a safe assumption). '\\' *may* be the second byte in a multibyte char
48  set.
49 ****************************************************************************/
50
51 /* Custom version for processing POSIX paths. */
52 #define IS_PATH_SEP(c,posix_only) ((c) == '/' || (!(posix_only) && (c) == '\\'))
53
54 static NTSTATUS check_path_syntax_internal(char *path,
55                                            bool posix_path,
56                                            bool *p_last_component_contains_wcard)
57 {
58         char *d = path;
59         const char *s = path;
60         NTSTATUS ret = NT_STATUS_OK;
61         bool start_of_name_component = True;
62         bool stream_started = false;
63
64         *p_last_component_contains_wcard = False;
65
66         while (*s) {
67                 if (stream_started) {
68                         switch (*s) {
69                         case '/':
70                         case '\\':
71                                 return NT_STATUS_OBJECT_NAME_INVALID;
72                         case ':':
73                                 if (s[1] == '\0') {
74                                         return NT_STATUS_OBJECT_NAME_INVALID;
75                                 }
76                                 if (strchr_m(&s[1], ':')) {
77                                         return NT_STATUS_OBJECT_NAME_INVALID;
78                                 }
79                                 break;
80                         }
81                 }
82
83                 if ((*s == ':') && !posix_path && !stream_started) {
84                         if (*p_last_component_contains_wcard) {
85                                 return NT_STATUS_OBJECT_NAME_INVALID;
86                         }
87                         /* Stream names allow more characters than file names.
88                            We're overloading posix_path here to allow a wider
89                            range of characters. If stream_started is true this
90                            is still a Windows path even if posix_path is true.
91                            JRA.
92                         */
93                         stream_started = true;
94                         start_of_name_component = false;
95                         posix_path = true;
96
97                         if (s[1] == '\0') {
98                                 return NT_STATUS_OBJECT_NAME_INVALID;
99                         }
100                 }
101
102                 if (!stream_started && IS_PATH_SEP(*s,posix_path)) {
103                         /*
104                          * Safe to assume is not the second part of a mb char
105                          * as this is handled below.
106                          */
107                         /* Eat multiple '/' or '\\' */
108                         while (IS_PATH_SEP(*s,posix_path)) {
109                                 s++;
110                         }
111                         if ((d != path) && (*s != '\0')) {
112                                 /* We only care about non-leading or trailing '/' or '\\' */
113                                 *d++ = '/';
114                         }
115
116                         start_of_name_component = True;
117                         /* New component. */
118                         *p_last_component_contains_wcard = False;
119                         continue;
120                 }
121
122                 if (start_of_name_component) {
123                         if ((s[0] == '.') && (s[1] == '.') && (IS_PATH_SEP(s[2],posix_path) || s[2] == '\0')) {
124                                 /* Uh oh - "/../" or "\\..\\"  or "/..\0" or "\\..\0" ! */
125
126                                 /*
127                                  * No mb char starts with '.' so we're safe checking the directory separator here.
128                                  */
129
130                                 /* If  we just added a '/' - delete it */
131                                 if ((d > path) && (*(d-1) == '/')) {
132                                         *(d-1) = '\0';
133                                         d--;
134                                 }
135
136                                 /* Are we at the start ? Can't go back further if so. */
137                                 if (d <= path) {
138                                         ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
139                                         break;
140                                 }
141                                 /* Go back one level... */
142                                 /* We know this is safe as '/' cannot be part of a mb sequence. */
143                                 /* NOTE - if this assumption is invalid we are not in good shape... */
144                                 /* Decrement d first as d points to the *next* char to write into. */
145                                 for (d--; d > path; d--) {
146                                         if (*d == '/')
147                                                 break;
148                                 }
149                                 s += 2; /* Else go past the .. */
150                                 /* We're still at the start of a name component, just the previous one. */
151                                 continue;
152
153                         } else if ((s[0] == '.') && ((s[1] == '\0') || IS_PATH_SEP(s[1],posix_path))) {
154                                 if (posix_path) {
155                                         /* Eat the '.' */
156                                         s++;
157                                         continue;
158                                 }
159                         }
160
161                 }
162
163                 if (!(*s & 0x80)) {
164                         if (!posix_path) {
165                                 if (*s <= 0x1f || *s == '|') {
166                                         return NT_STATUS_OBJECT_NAME_INVALID;
167                                 }
168                                 switch (*s) {
169                                         case '*':
170                                         case '?':
171                                         case '<':
172                                         case '>':
173                                         case '"':
174                                                 *p_last_component_contains_wcard = True;
175                                                 break;
176                                         default:
177                                                 break;
178                                 }
179                         }
180                         *d++ = *s++;
181                 } else {
182                         size_t siz;
183                         /* Get the size of the next MB character. */
184                         next_codepoint(s,&siz);
185                         switch(siz) {
186                                 case 5:
187                                         *d++ = *s++;
188                                         /*fall through*/
189                                 case 4:
190                                         *d++ = *s++;
191                                         /*fall through*/
192                                 case 3:
193                                         *d++ = *s++;
194                                         /*fall through*/
195                                 case 2:
196                                         *d++ = *s++;
197                                         /*fall through*/
198                                 case 1:
199                                         *d++ = *s++;
200                                         break;
201                                 default:
202                                         DEBUG(0,("check_path_syntax_internal: character length assumptions invalid !\n"));
203                                         *d = '\0';
204                                         return NT_STATUS_INVALID_PARAMETER;
205                         }
206                 }
207                 start_of_name_component = False;
208         }
209
210         *d = '\0';
211
212         return ret;
213 }
214
215 /****************************************************************************
216  Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
217  No wildcards allowed.
218 ****************************************************************************/
219
220 NTSTATUS check_path_syntax(char *path)
221 {
222         bool ignore;
223         return check_path_syntax_internal(path, False, &ignore);
224 }
225
226 /****************************************************************************
227  Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
228  Wildcards allowed - p_contains_wcard returns true if the last component contained
229  a wildcard.
230 ****************************************************************************/
231
232 NTSTATUS check_path_syntax_wcard(char *path, bool *p_contains_wcard)
233 {
234         return check_path_syntax_internal(path, False, p_contains_wcard);
235 }
236
237 /****************************************************************************
238  Check the path for a POSIX client.
239  We're assuming here that '/' is not the second byte in any multibyte char
240  set (a safe assumption).
241 ****************************************************************************/
242
243 NTSTATUS check_path_syntax_posix(char *path)
244 {
245         bool ignore;
246         return check_path_syntax_internal(path, True, &ignore);
247 }
248
249 /****************************************************************************
250  Pull a string and check the path allowing a wilcard - provide for error return.
251 ****************************************************************************/
252
253 size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
254                         const char *base_ptr,
255                         uint16 smb_flags2,
256                         char **pp_dest,
257                         const char *src,
258                         size_t src_len,
259                         int flags,
260                         NTSTATUS *err,
261                         bool *contains_wcard)
262 {
263         size_t ret;
264
265         *pp_dest = NULL;
266
267         ret = srvstr_pull_talloc(ctx, base_ptr, smb_flags2, pp_dest, src,
268                                  src_len, flags);
269
270         if (!*pp_dest) {
271                 *err = NT_STATUS_INVALID_PARAMETER;
272                 return ret;
273         }
274
275         *contains_wcard = False;
276
277         if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
278                 /*
279                  * For a DFS path the function parse_dfs_path()
280                  * will do the path processing, just make a copy.
281                  */
282                 *err = NT_STATUS_OK;
283                 return ret;
284         }
285
286         if (lp_posix_pathnames()) {
287                 *err = check_path_syntax_posix(*pp_dest);
288         } else {
289                 *err = check_path_syntax_wcard(*pp_dest, contains_wcard);
290         }
291
292         return ret;
293 }
294
295 /****************************************************************************
296  Pull a string and check the path - provide for error return.
297 ****************************************************************************/
298
299 size_t srvstr_get_path(TALLOC_CTX *ctx,
300                         const char *base_ptr,
301                         uint16 smb_flags2,
302                         char **pp_dest,
303                         const char *src,
304                         size_t src_len,
305                         int flags,
306                         NTSTATUS *err)
307 {
308         bool ignore;
309         return srvstr_get_path_wcard(ctx, base_ptr, smb_flags2, pp_dest, src,
310                                      src_len, flags, err, &ignore);
311 }
312
313 size_t srvstr_get_path_req_wcard(TALLOC_CTX *mem_ctx, struct smb_request *req,
314                                  char **pp_dest, const char *src, int flags,
315                                  NTSTATUS *err, bool *contains_wcard)
316 {
317         return srvstr_get_path_wcard(mem_ctx, (const char *)req->inbuf, req->flags2,
318                                      pp_dest, src, smbreq_bufrem(req, src),
319                                      flags, err, contains_wcard);
320 }
321
322 size_t srvstr_get_path_req(TALLOC_CTX *mem_ctx, struct smb_request *req,
323                            char **pp_dest, const char *src, int flags,
324                            NTSTATUS *err)
325 {
326         bool ignore;
327         return srvstr_get_path_req_wcard(mem_ctx, req, pp_dest, src,
328                                          flags, err, &ignore);
329 }
330
331 /****************************************************************************
332  Check if we have a correct fsp pointing to a file. Basic check for open fsp.
333 ****************************************************************************/
334
335 bool check_fsp_open(connection_struct *conn, struct smb_request *req,
336                     files_struct *fsp)
337 {
338         if ((fsp == NULL) || (conn == NULL)) {
339                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
340                 return False;
341         }
342         if ((conn != fsp->conn) || (req->vuid != fsp->vuid)) {
343                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
344                 return False;
345         }
346         return True;
347 }
348
349 /****************************************************************************
350  Check if we have a correct fsp pointing to a file.
351 ****************************************************************************/
352
353 bool check_fsp(connection_struct *conn, struct smb_request *req,
354                files_struct *fsp)
355 {
356         if (!check_fsp_open(conn, req, fsp)) {
357                 return False;
358         }
359         if (fsp->is_directory) {
360                 reply_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
361                 return False;
362         }
363         if (fsp->fh->fd == -1) {
364                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
365                 return False;
366         }
367         fsp->num_smb_operations++;
368         return True;
369 }
370
371 /****************************************************************************
372  Check if we have a correct fsp pointing to a quota fake file. Replacement for
373  the CHECK_NTQUOTA_HANDLE_OK macro.
374 ****************************************************************************/
375
376 bool check_fsp_ntquota_handle(connection_struct *conn, struct smb_request *req,
377                               files_struct *fsp)
378 {
379         if (!check_fsp_open(conn, req, fsp)) {
380                 return false;
381         }
382
383         if (fsp->is_directory) {
384                 return false;
385         }
386
387         if (fsp->fake_file_handle == NULL) {
388                 return false;
389         }
390
391         if (fsp->fake_file_handle->type != FAKE_FILE_TYPE_QUOTA) {
392                 return false;
393         }
394
395         if (fsp->fake_file_handle->private_data == NULL) {
396                 return false;
397         }
398
399         return true;
400 }
401
402 static bool netbios_session_retarget(struct smbd_server_connection *sconn,
403                                      const char *name, int name_type)
404 {
405         char *trim_name;
406         char *trim_name_type;
407         const char *retarget_parm;
408         char *retarget;
409         char *p;
410         int retarget_type = 0x20;
411         int retarget_port = 139;
412         struct sockaddr_storage retarget_addr;
413         struct sockaddr_in *in_addr;
414         bool ret = false;
415         uint8_t outbuf[10];
416
417         if (get_socket_port(sconn->sock) != 139) {
418                 return false;
419         }
420
421         trim_name = talloc_strdup(talloc_tos(), name);
422         if (trim_name == NULL) {
423                 goto fail;
424         }
425         trim_char(trim_name, ' ', ' ');
426
427         trim_name_type = talloc_asprintf(trim_name, "%s#%2.2x", trim_name,
428                                          name_type);
429         if (trim_name_type == NULL) {
430                 goto fail;
431         }
432
433         retarget_parm = lp_parm_const_string(-1, "netbios retarget",
434                                              trim_name_type, NULL);
435         if (retarget_parm == NULL) {
436                 retarget_parm = lp_parm_const_string(-1, "netbios retarget",
437                                                      trim_name, NULL);
438         }
439         if (retarget_parm == NULL) {
440                 goto fail;
441         }
442
443         retarget = talloc_strdup(trim_name, retarget_parm);
444         if (retarget == NULL) {
445                 goto fail;
446         }
447
448         DEBUG(10, ("retargeting %s to %s\n", trim_name_type, retarget));
449
450         p = strchr(retarget, ':');
451         if (p != NULL) {
452                 *p++ = '\0';
453                 retarget_port = atoi(p);
454         }
455
456         p = strchr_m(retarget, '#');
457         if (p != NULL) {
458                 *p++ = '\0';
459                 if (sscanf(p, "%x", &retarget_type) != 1) {
460                         goto fail;
461                 }
462         }
463
464         ret = resolve_name(retarget, &retarget_addr, retarget_type, false);
465         if (!ret) {
466                 DEBUG(10, ("could not resolve %s\n", retarget));
467                 goto fail;
468         }
469
470         if (retarget_addr.ss_family != AF_INET) {
471                 DEBUG(10, ("Retarget target not an IPv4 addr\n"));
472                 goto fail;
473         }
474
475         in_addr = (struct sockaddr_in *)(void *)&retarget_addr;
476
477         _smb_setlen(outbuf, 6);
478         SCVAL(outbuf, 0, 0x84);
479         *(uint32_t *)(outbuf+4) = in_addr->sin_addr.s_addr;
480         *(uint16_t *)(outbuf+8) = htons(retarget_port);
481
482         if (!srv_send_smb(sconn, (char *)outbuf, false, 0, false,
483                           NULL)) {
484                 exit_server_cleanly("netbios_session_regarget: srv_send_smb "
485                                     "failed.");
486         }
487
488         ret = true;
489  fail:
490         TALLOC_FREE(trim_name);
491         return ret;
492 }
493
494 static void reply_called_name_not_present(char *outbuf)
495 {
496         smb_setlen(outbuf, 1);
497         SCVAL(outbuf, 0, 0x83);
498         SCVAL(outbuf, 4, 0x82);
499 }
500
501 /****************************************************************************
502  Reply to a (netbios-level) special message. 
503 ****************************************************************************/
504
505 void reply_special(struct smbd_server_connection *sconn, char *inbuf, size_t inbuf_size)
506 {
507         int msg_type = CVAL(inbuf,0);
508         int msg_flags = CVAL(inbuf,1);
509         /*
510          * We only really use 4 bytes of the outbuf, but for the smb_setlen
511          * calculation & friends (srv_send_smb uses that) we need the full smb
512          * header.
513          */
514         char outbuf[smb_size];
515
516         memset(outbuf, '\0', sizeof(outbuf));
517
518         smb_setlen(outbuf,0);
519
520         switch (msg_type) {
521         case 0x81: /* session request */
522         {
523                 /* inbuf_size is guarenteed to be at least 4. */
524                 fstring name1,name2;
525                 int name_type1, name_type2;
526                 int name_len1, name_len2;
527
528                 *name1 = *name2 = 0;
529
530                 if (sconn->nbt.got_session) {
531                         exit_server_cleanly("multiple session request not permitted");
532                 }
533
534                 SCVAL(outbuf,0,0x82);
535                 SCVAL(outbuf,3,0);
536
537                 /* inbuf_size is guaranteed to be at least 4. */
538                 name_len1 = name_len((unsigned char *)(inbuf+4),inbuf_size - 4);
539                 if (name_len1 <= 0 || name_len1 > inbuf_size - 4) {
540                         DEBUG(0,("Invalid name length in session request\n"));
541                         reply_called_name_not_present(outbuf);
542                         break;
543                 }
544                 name_len2 = name_len((unsigned char *)(inbuf+4+name_len1),inbuf_size - 4 - name_len1);
545                 if (name_len2 <= 0 || name_len2 > inbuf_size - 4 - name_len1) {
546                         DEBUG(0,("Invalid name length in session request\n"));
547                         reply_called_name_not_present(outbuf);
548                         break;
549                 }
550
551                 name_type1 = name_extract((unsigned char *)inbuf,
552                                 inbuf_size,(unsigned int)4,name1);
553                 name_type2 = name_extract((unsigned char *)inbuf,
554                                 inbuf_size,(unsigned int)(4 + name_len1),name2);
555
556                 if (name_type1 == -1 || name_type2 == -1) {
557                         DEBUG(0,("Invalid name type in session request\n"));
558                         reply_called_name_not_present(outbuf);
559                         break;
560                 }
561
562                 DEBUG(2,("netbios connect: name1=%s0x%x name2=%s0x%x\n",
563                          name1, name_type1, name2, name_type2));
564
565                 if (netbios_session_retarget(sconn, name1, name_type1)) {
566                         exit_server_cleanly("retargeted client");
567                 }
568
569                 /*
570                  * Windows NT/2k uses "*SMBSERVER" and XP uses
571                  * "*SMBSERV" arrggg!!!
572                  */
573                 if (strequal(name1, "*SMBSERVER     ")
574                     || strequal(name1, "*SMBSERV       "))  {
575                         fstrcpy(name1, sconn->client_id.addr);
576                 }
577
578                 set_local_machine_name(name1, True);
579                 set_remote_machine_name(name2, True);
580
581                 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
582                          get_local_machine_name(), get_remote_machine_name(),
583                          name_type2));
584
585                 if (name_type2 == 'R') {
586                         /* We are being asked for a pathworks session --- 
587                            no thanks! */
588                         reply_called_name_not_present(outbuf);
589                         break;
590                 }
591
592                 /* only add the client's machine name to the list
593                    of possibly valid usernames if we are operating
594                    in share mode security */
595                 if (lp_security() == SEC_SHARE) {
596                         add_session_user(sconn, get_remote_machine_name());
597                 }
598
599                 reload_services(sconn->msg_ctx, sconn->sock, True);
600                 reopen_logs();
601
602                 sconn->nbt.got_session = true;
603                 break;
604         }
605
606         case 0x89: /* session keepalive request 
607                       (some old clients produce this?) */
608                 SCVAL(outbuf,0,SMBkeepalive);
609                 SCVAL(outbuf,3,0);
610                 break;
611
612         case 0x82: /* positive session response */
613         case 0x83: /* negative session response */
614         case 0x84: /* retarget session response */
615                 DEBUG(0,("Unexpected session response\n"));
616                 break;
617
618         case SMBkeepalive: /* session keepalive */
619         default:
620                 return;
621         }
622
623         DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
624                     msg_type, msg_flags));
625
626         srv_send_smb(sconn, outbuf, false, 0, false, NULL);
627
628         if (CVAL(outbuf, 0) != 0x82) {
629                 exit_server_cleanly("invalid netbios session");
630         }
631         return;
632 }
633
634 /****************************************************************************
635  Reply to a tcon.
636  conn POINTER CAN BE NULL HERE !
637 ****************************************************************************/
638
639 void reply_tcon(struct smb_request *req)
640 {
641         connection_struct *conn = req->conn;
642         const char *service;
643         char *service_buf = NULL;
644         char *password = NULL;
645         char *dev = NULL;
646         int pwlen=0;
647         NTSTATUS nt_status;
648         const char *p;
649         DATA_BLOB password_blob;
650         TALLOC_CTX *ctx = talloc_tos();
651         struct smbd_server_connection *sconn = req->sconn;
652
653         START_PROFILE(SMBtcon);
654
655         if (req->buflen < 4) {
656                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
657                 END_PROFILE(SMBtcon);
658                 return;
659         }
660
661         p = (const char *)req->buf + 1;
662         p += srvstr_pull_req_talloc(ctx, req, &service_buf, p, STR_TERMINATE);
663         p += 1;
664         pwlen = srvstr_pull_req_talloc(ctx, req, &password, p, STR_TERMINATE);
665         p += pwlen+1;
666         p += srvstr_pull_req_talloc(ctx, req, &dev, p, STR_TERMINATE);
667         p += 1;
668
669         if (service_buf == NULL || password == NULL || dev == NULL) {
670                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
671                 END_PROFILE(SMBtcon);
672                 return;
673         }
674         p = strrchr_m(service_buf,'\\');
675         if (p) {
676                 service = p+1;
677         } else {
678                 service = service_buf;
679         }
680
681         password_blob = data_blob(password, pwlen+1);
682
683         conn = make_connection(sconn,service,password_blob,dev,
684                                req->vuid,&nt_status);
685         req->conn = conn;
686
687         data_blob_clear_free(&password_blob);
688
689         if (!conn) {
690                 reply_nterror(req, nt_status);
691                 END_PROFILE(SMBtcon);
692                 return;
693         }
694
695         reply_outbuf(req, 2, 0);
696         SSVAL(req->outbuf,smb_vwv0,sconn->smb1.negprot.max_recv);
697         SSVAL(req->outbuf,smb_vwv1,conn->cnum);
698         SSVAL(req->outbuf,smb_tid,conn->cnum);
699
700         DEBUG(3,("tcon service=%s cnum=%d\n",
701                  service, conn->cnum));
702
703         END_PROFILE(SMBtcon);
704         return;
705 }
706
707 /****************************************************************************
708  Reply to a tcon and X.
709  conn POINTER CAN BE NULL HERE !
710 ****************************************************************************/
711
712 void reply_tcon_and_X(struct smb_request *req)
713 {
714         connection_struct *conn = req->conn;
715         const char *service = NULL;
716         DATA_BLOB password;
717         TALLOC_CTX *ctx = talloc_tos();
718         /* what the cleint thinks the device is */
719         char *client_devicetype = NULL;
720         /* what the server tells the client the share represents */
721         const char *server_devicetype;
722         NTSTATUS nt_status;
723         int passlen;
724         char *path = NULL;
725         const char *p, *q;
726         uint16 tcon_flags;
727         struct smbd_server_connection *sconn = req->sconn;
728
729         START_PROFILE(SMBtconX);
730
731         if (req->wct < 4) {
732                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
733                 END_PROFILE(SMBtconX);
734                 return;
735         }
736
737         passlen = SVAL(req->vwv+3, 0);
738         tcon_flags = SVAL(req->vwv+2, 0);
739
740         /* we might have to close an old one */
741         if ((tcon_flags & 0x1) && conn) {
742                 close_cnum(conn,req->vuid);
743                 req->conn = NULL;
744                 conn = NULL;
745         }
746
747         if ((passlen > MAX_PASS_LEN) || (passlen >= req->buflen)) {
748                 reply_force_doserror(req, ERRDOS, ERRbuftoosmall);
749                 END_PROFILE(SMBtconX);
750                 return;
751         }
752
753         if (sconn->smb1.negprot.encrypted_passwords) {
754                 password = data_blob_talloc(talloc_tos(), req->buf, passlen);
755                 if (lp_security() == SEC_SHARE) {
756                         /*
757                          * Security = share always has a pad byte
758                          * after the password.
759                          */
760                         p = (const char *)req->buf + passlen + 1;
761                 } else {
762                         p = (const char *)req->buf + passlen;
763                 }
764         } else {
765                 password = data_blob_talloc(talloc_tos(), req->buf, passlen+1);
766                 /* Ensure correct termination */
767                 password.data[passlen]=0;
768                 p = (const char *)req->buf + passlen + 1;
769         }
770
771         p += srvstr_pull_req_talloc(ctx, req, &path, p, STR_TERMINATE);
772
773         if (path == NULL) {
774                 data_blob_clear_free(&password);
775                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
776                 END_PROFILE(SMBtconX);
777                 return;
778         }
779
780         /*
781          * the service name can be either: \\server\share
782          * or share directly like on the DELL PowerVault 705
783          */
784         if (*path=='\\') {
785                 q = strchr_m(path+2,'\\');
786                 if (!q) {
787                         data_blob_clear_free(&password);
788                         reply_nterror(req, NT_STATUS_BAD_NETWORK_NAME);
789                         END_PROFILE(SMBtconX);
790                         return;
791                 }
792                 service = q+1;
793         } else {
794                 service = path;
795         }
796
797         p += srvstr_pull_talloc(ctx, req->inbuf, req->flags2,
798                                 &client_devicetype, p,
799                                 MIN(6, smbreq_bufrem(req, p)), STR_ASCII);
800
801         if (client_devicetype == NULL) {
802                 data_blob_clear_free(&password);
803                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
804                 END_PROFILE(SMBtconX);
805                 return;
806         }
807
808         DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
809
810         conn = make_connection(sconn, service, password, client_devicetype,
811                                req->vuid, &nt_status);
812         req->conn =conn;
813
814         data_blob_clear_free(&password);
815
816         if (!conn) {
817                 reply_nterror(req, nt_status);
818                 END_PROFILE(SMBtconX);
819                 return;
820         }
821
822         if ( IS_IPC(conn) )
823                 server_devicetype = "IPC";
824         else if ( IS_PRINT(conn) )
825                 server_devicetype = "LPT1:";
826         else
827                 server_devicetype = "A:";
828
829         if (get_Protocol() < PROTOCOL_NT1) {
830                 reply_outbuf(req, 2, 0);
831                 if (message_push_string(&req->outbuf, server_devicetype,
832                                         STR_TERMINATE|STR_ASCII) == -1) {
833                         reply_nterror(req, NT_STATUS_NO_MEMORY);
834                         END_PROFILE(SMBtconX);
835                         return;
836                 }
837         } else {
838                 /* NT sets the fstype of IPC$ to the null string */
839                 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
840
841                 if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) {
842                         /* Return permissions. */
843                         uint32 perm1 = 0;
844                         uint32 perm2 = 0;
845
846                         reply_outbuf(req, 7, 0);
847
848                         if (IS_IPC(conn)) {
849                                 perm1 = FILE_ALL_ACCESS;
850                                 perm2 = FILE_ALL_ACCESS;
851                         } else {
852                                 perm1 = CAN_WRITE(conn) ?
853                                                 SHARE_ALL_ACCESS :
854                                                 SHARE_READ_ONLY;
855                         }
856
857                         SIVAL(req->outbuf, smb_vwv3, perm1);
858                         SIVAL(req->outbuf, smb_vwv5, perm2);
859                 } else {
860                         reply_outbuf(req, 3, 0);
861                 }
862
863                 if ((message_push_string(&req->outbuf, server_devicetype,
864                                          STR_TERMINATE|STR_ASCII) == -1)
865                     || (message_push_string(&req->outbuf, fstype,
866                                             STR_TERMINATE) == -1)) {
867                         reply_nterror(req, NT_STATUS_NO_MEMORY);
868                         END_PROFILE(SMBtconX);
869                         return;
870                 }
871
872                 /* what does setting this bit do? It is set by NT4 and
873                    may affect the ability to autorun mounted cdroms */
874                 SSVAL(req->outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS|
875                       (lp_csc_policy(SNUM(conn)) << 2));
876
877                 if (lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) {
878                         DEBUG(2,("Serving %s as a Dfs root\n",
879                                  lp_servicename(SNUM(conn)) ));
880                         SSVAL(req->outbuf, smb_vwv2,
881                               SMB_SHARE_IN_DFS | SVAL(req->outbuf, smb_vwv2));
882                 }
883         }
884
885
886         DEBUG(3,("tconX service=%s \n",
887                  service));
888
889         /* set the incoming and outgoing tid to the just created one */
890         SSVAL(discard_const_p(uint8_t, req->inbuf),smb_tid,conn->cnum);
891         SSVAL(req->outbuf,smb_tid,conn->cnum);
892
893         END_PROFILE(SMBtconX);
894
895         req->tid = conn->cnum;
896         chain_reply(req);
897         return;
898 }
899
900 /****************************************************************************
901  Reply to an unknown type.
902 ****************************************************************************/
903
904 void reply_unknown_new(struct smb_request *req, uint8 type)
905 {
906         DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
907                   smb_fn_name(type), type, type));
908         reply_force_doserror(req, ERRSRV, ERRunknownsmb);
909         return;
910 }
911
912 /****************************************************************************
913  Reply to an ioctl.
914  conn POINTER CAN BE NULL HERE !
915 ****************************************************************************/
916
917 void reply_ioctl(struct smb_request *req)
918 {
919         connection_struct *conn = req->conn;
920         uint16 device;
921         uint16 function;
922         uint32 ioctl_code;
923         int replysize;
924         char *p;
925
926         START_PROFILE(SMBioctl);
927
928         if (req->wct < 3) {
929                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
930                 END_PROFILE(SMBioctl);
931                 return;
932         }
933
934         device     = SVAL(req->vwv+1, 0);
935         function   = SVAL(req->vwv+2, 0);
936         ioctl_code = (device << 16) + function;
937
938         DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
939
940         switch (ioctl_code) {
941             case IOCTL_QUERY_JOB_INFO:
942                     replysize = 32;
943                     break;
944             default:
945                     reply_force_doserror(req, ERRSRV, ERRnosupport);
946                     END_PROFILE(SMBioctl);
947                     return;
948         }
949
950         reply_outbuf(req, 8, replysize+1);
951         SSVAL(req->outbuf,smb_vwv1,replysize); /* Total data bytes returned */
952         SSVAL(req->outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
953         SSVAL(req->outbuf,smb_vwv6,52);        /* Offset to data */
954         p = smb_buf(req->outbuf);
955         memset(p, '\0', replysize+1); /* valgrind-safe. */
956         p += 1;          /* Allow for alignment */
957
958         switch (ioctl_code) {
959                 case IOCTL_QUERY_JOB_INFO:                  
960                 {
961                         files_struct *fsp = file_fsp(
962                                 req, SVAL(req->vwv+0, 0));
963                         if (!fsp) {
964                                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
965                                 END_PROFILE(SMBioctl);
966                                 return;
967                         }
968                         /* Job number */
969                         if (fsp->print_file) {
970                                 SSVAL(p, 0, fsp->print_file->rap_jobid);
971                         } else {
972                                 SSVAL(p, 0, 0);
973                         }
974                         srvstr_push((char *)req->outbuf, req->flags2, p+2,
975                                     global_myname(), 15,
976                                     STR_TERMINATE|STR_ASCII);
977                         if (conn) {
978                                 srvstr_push((char *)req->outbuf, req->flags2,
979                                             p+18, lp_servicename(SNUM(conn)),
980                                             13, STR_TERMINATE|STR_ASCII);
981                         } else {
982                                 memset(p+18, 0, 13);
983                         }
984                         break;
985                 }
986         }
987
988         END_PROFILE(SMBioctl);
989         return;
990 }
991
992 /****************************************************************************
993  Strange checkpath NTSTATUS mapping.
994 ****************************************************************************/
995
996 static NTSTATUS map_checkpath_error(uint16_t flags2, NTSTATUS status)
997 {
998         /* Strange DOS error code semantics only for checkpath... */
999         if (!(flags2 & FLAGS2_32_BIT_ERROR_CODES)) {
1000                 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
1001                         /* We need to map to ERRbadpath */
1002                         return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1003                 }
1004         }
1005         return status;
1006 }
1007
1008 /****************************************************************************
1009  Reply to a checkpath.
1010 ****************************************************************************/
1011
1012 void reply_checkpath(struct smb_request *req)
1013 {
1014         connection_struct *conn = req->conn;
1015         struct smb_filename *smb_fname = NULL;
1016         char *name = NULL;
1017         NTSTATUS status;
1018         TALLOC_CTX *ctx = talloc_tos();
1019
1020         START_PROFILE(SMBcheckpath);
1021
1022         srvstr_get_path_req(ctx, req, &name, (const char *)req->buf + 1,
1023                             STR_TERMINATE, &status);
1024
1025         if (!NT_STATUS_IS_OK(status)) {
1026                 status = map_checkpath_error(req->flags2, status);
1027                 reply_nterror(req, status);
1028                 END_PROFILE(SMBcheckpath);
1029                 return;
1030         }
1031
1032         DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->vwv+0, 0)));
1033
1034         status = filename_convert(ctx,
1035                                 conn,
1036                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
1037                                 name,
1038                                 0,
1039                                 NULL,
1040                                 &smb_fname);
1041
1042         if (!NT_STATUS_IS_OK(status)) {
1043                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1044                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1045                                         ERRSRV, ERRbadpath);
1046                         END_PROFILE(SMBcheckpath);
1047                         return;
1048                 }
1049                 goto path_err;
1050         }
1051
1052         if (!VALID_STAT(smb_fname->st) &&
1053             (SMB_VFS_STAT(conn, smb_fname) != 0)) {
1054                 DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",
1055                         smb_fname_str_dbg(smb_fname), strerror(errno)));
1056                 status = map_nt_error_from_unix(errno);
1057                 goto path_err;
1058         }
1059
1060         if (!S_ISDIR(smb_fname->st.st_ex_mode)) {
1061                 reply_botherror(req, NT_STATUS_NOT_A_DIRECTORY,
1062                                 ERRDOS, ERRbadpath);
1063                 goto out;
1064         }
1065
1066         reply_outbuf(req, 0, 0);
1067
1068  path_err:
1069         /* We special case this - as when a Windows machine
1070                 is parsing a path is steps through the components
1071                 one at a time - if a component fails it expects
1072                 ERRbadpath, not ERRbadfile.
1073         */
1074         status = map_checkpath_error(req->flags2, status);
1075         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1076                 /*
1077                  * Windows returns different error codes if
1078                  * the parent directory is valid but not the
1079                  * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
1080                  * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
1081                  * if the path is invalid.
1082                  */
1083                 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
1084                                 ERRDOS, ERRbadpath);
1085                 goto out;
1086         }
1087
1088         reply_nterror(req, status);
1089
1090  out:
1091         TALLOC_FREE(smb_fname);
1092         END_PROFILE(SMBcheckpath);
1093         return;
1094 }
1095
1096 /****************************************************************************
1097  Reply to a getatr.
1098 ****************************************************************************/
1099
1100 void reply_getatr(struct smb_request *req)
1101 {
1102         connection_struct *conn = req->conn;
1103         struct smb_filename *smb_fname = NULL;
1104         char *fname = NULL;
1105         int mode=0;
1106         SMB_OFF_T size=0;
1107         time_t mtime=0;
1108         const char *p;
1109         NTSTATUS status;
1110         TALLOC_CTX *ctx = talloc_tos();
1111         bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1112
1113         START_PROFILE(SMBgetatr);
1114
1115         p = (const char *)req->buf + 1;
1116         p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status);
1117         if (!NT_STATUS_IS_OK(status)) {
1118                 reply_nterror(req, status);
1119                 goto out;
1120         }
1121
1122         /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
1123                 under WfWg - weird! */
1124         if (*fname == '\0') {
1125                 mode = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY;
1126                 if (!CAN_WRITE(conn)) {
1127                         mode |= FILE_ATTRIBUTE_READONLY;
1128                 }
1129                 size = 0;
1130                 mtime = 0;
1131         } else {
1132                 status = filename_convert(ctx,
1133                                 conn,
1134                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
1135                                 fname,
1136                                 0,
1137                                 NULL,
1138                                 &smb_fname);
1139                 if (!NT_STATUS_IS_OK(status)) {
1140                         if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1141                                 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1142                                                 ERRSRV, ERRbadpath);
1143                                 goto out;
1144                         }
1145                         reply_nterror(req, status);
1146                         goto out;
1147                 }
1148                 if (!VALID_STAT(smb_fname->st) &&
1149                     (SMB_VFS_STAT(conn, smb_fname) != 0)) {
1150                         DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",
1151                                  smb_fname_str_dbg(smb_fname),
1152                                  strerror(errno)));
1153                         reply_nterror(req,  map_nt_error_from_unix(errno));
1154                         goto out;
1155                 }
1156
1157                 mode = dos_mode(conn, smb_fname);
1158                 size = smb_fname->st.st_ex_size;
1159
1160                 if (ask_sharemode) {
1161                         struct timespec write_time_ts;
1162                         struct file_id fileid;
1163
1164                         ZERO_STRUCT(write_time_ts);
1165                         fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1166                         get_file_infos(fileid, 0, NULL, &write_time_ts);
1167                         if (!null_timespec(write_time_ts)) {
1168                                 update_stat_ex_mtime(&smb_fname->st, write_time_ts);
1169                         }
1170                 }
1171
1172                 mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1173                 if (mode & FILE_ATTRIBUTE_DIRECTORY) {
1174                         size = 0;
1175                 }
1176         }
1177
1178         reply_outbuf(req, 10, 0);
1179
1180         SSVAL(req->outbuf,smb_vwv0,mode);
1181         if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1182                 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime & ~1);
1183         } else {
1184                 srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime);
1185         }
1186         SIVAL(req->outbuf,smb_vwv3,(uint32)size);
1187
1188         if (get_Protocol() >= PROTOCOL_NT1) {
1189                 SSVAL(req->outbuf, smb_flg2,
1190                       SVAL(req->outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
1191         }
1192
1193         DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n",
1194                  smb_fname_str_dbg(smb_fname), mode, (unsigned int)size));
1195
1196  out:
1197         TALLOC_FREE(smb_fname);
1198         TALLOC_FREE(fname);
1199         END_PROFILE(SMBgetatr);
1200         return;
1201 }
1202
1203 /****************************************************************************
1204  Reply to a setatr.
1205 ****************************************************************************/
1206
1207 void reply_setatr(struct smb_request *req)
1208 {
1209         struct smb_file_time ft;
1210         connection_struct *conn = req->conn;
1211         struct smb_filename *smb_fname = NULL;
1212         char *fname = NULL;
1213         int mode;
1214         time_t mtime;
1215         const char *p;
1216         NTSTATUS status;
1217         TALLOC_CTX *ctx = talloc_tos();
1218
1219         START_PROFILE(SMBsetatr);
1220
1221         ZERO_STRUCT(ft);
1222
1223         if (req->wct < 2) {
1224                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1225                 goto out;
1226         }
1227
1228         p = (const char *)req->buf + 1;
1229         p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status);
1230         if (!NT_STATUS_IS_OK(status)) {
1231                 reply_nterror(req, status);
1232                 goto out;
1233         }
1234
1235         status = filename_convert(ctx,
1236                                 conn,
1237                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
1238                                 fname,
1239                                 0,
1240                                 NULL,
1241                                 &smb_fname);
1242         if (!NT_STATUS_IS_OK(status)) {
1243                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1244                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1245                                         ERRSRV, ERRbadpath);
1246                         goto out;
1247                 }
1248                 reply_nterror(req, status);
1249                 goto out;
1250         }
1251
1252         if (smb_fname->base_name[0] == '.' &&
1253             smb_fname->base_name[1] == '\0') {
1254                 /*
1255                  * Not sure here is the right place to catch this
1256                  * condition. Might be moved to somewhere else later -- vl
1257                  */
1258                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1259                 goto out;
1260         }
1261
1262         mode = SVAL(req->vwv+0, 0);
1263         mtime = srv_make_unix_date3(req->vwv+1);
1264
1265         ft.mtime = convert_time_t_to_timespec(mtime);
1266         status = smb_set_file_time(conn, NULL, smb_fname, &ft, true);
1267         if (!NT_STATUS_IS_OK(status)) {
1268                 reply_nterror(req, status);
1269                 goto out;
1270         }
1271
1272         if (mode != FILE_ATTRIBUTE_NORMAL) {
1273                 if (VALID_STAT_OF_DIR(smb_fname->st))
1274                         mode |= FILE_ATTRIBUTE_DIRECTORY;
1275                 else
1276                         mode &= ~FILE_ATTRIBUTE_DIRECTORY;
1277
1278                 if (file_set_dosmode(conn, smb_fname, mode, NULL,
1279                                      false) != 0) {
1280                         reply_nterror(req, map_nt_error_from_unix(errno));
1281                         goto out;
1282                 }
1283         }
1284
1285         reply_outbuf(req, 0, 0);
1286
1287         DEBUG(3, ("setatr name=%s mode=%d\n", smb_fname_str_dbg(smb_fname),
1288                  mode));
1289  out:
1290         TALLOC_FREE(smb_fname);
1291         END_PROFILE(SMBsetatr);
1292         return;
1293 }
1294
1295 /****************************************************************************
1296  Reply to a dskattr.
1297 ****************************************************************************/
1298
1299 void reply_dskattr(struct smb_request *req)
1300 {
1301         connection_struct *conn = req->conn;
1302         uint64_t dfree,dsize,bsize;
1303         START_PROFILE(SMBdskattr);
1304
1305         if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) {
1306                 reply_nterror(req, map_nt_error_from_unix(errno));
1307                 END_PROFILE(SMBdskattr);
1308                 return;
1309         }
1310
1311         reply_outbuf(req, 5, 0);
1312
1313         if (get_Protocol() <= PROTOCOL_LANMAN2) {
1314                 double total_space, free_space;
1315                 /* we need to scale this to a number that DOS6 can handle. We
1316                    use floating point so we can handle large drives on systems
1317                    that don't have 64 bit integers 
1318
1319                    we end up displaying a maximum of 2G to DOS systems
1320                 */
1321                 total_space = dsize * (double)bsize;
1322                 free_space = dfree * (double)bsize;
1323
1324                 dsize = (uint64_t)((total_space+63*512) / (64*512));
1325                 dfree = (uint64_t)((free_space+63*512) / (64*512));
1326
1327                 if (dsize > 0xFFFF) dsize = 0xFFFF;
1328                 if (dfree > 0xFFFF) dfree = 0xFFFF;
1329
1330                 SSVAL(req->outbuf,smb_vwv0,dsize);
1331                 SSVAL(req->outbuf,smb_vwv1,64); /* this must be 64 for dos systems */
1332                 SSVAL(req->outbuf,smb_vwv2,512); /* and this must be 512 */
1333                 SSVAL(req->outbuf,smb_vwv3,dfree);
1334         } else {
1335                 SSVAL(req->outbuf,smb_vwv0,dsize);
1336                 SSVAL(req->outbuf,smb_vwv1,bsize/512);
1337                 SSVAL(req->outbuf,smb_vwv2,512);
1338                 SSVAL(req->outbuf,smb_vwv3,dfree);
1339         }
1340
1341         DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
1342
1343         END_PROFILE(SMBdskattr);
1344         return;
1345 }
1346
1347 /*
1348  * Utility function to split the filename from the directory.
1349  */
1350 static NTSTATUS split_fname_dir_mask(TALLOC_CTX *ctx, const char *fname_in,
1351                                      char **fname_dir_out,
1352                                      char **fname_mask_out)
1353 {
1354         const char *p = NULL;
1355         char *fname_dir = NULL;
1356         char *fname_mask = NULL;
1357
1358         p = strrchr_m(fname_in, '/');
1359         if (!p) {
1360                 fname_dir = talloc_strdup(ctx, ".");
1361                 fname_mask = talloc_strdup(ctx, fname_in);
1362         } else {
1363                 fname_dir = talloc_strndup(ctx, fname_in,
1364                     PTR_DIFF(p, fname_in));
1365                 fname_mask = talloc_strdup(ctx, p+1);
1366         }
1367
1368         if (!fname_dir || !fname_mask) {
1369                 TALLOC_FREE(fname_dir);
1370                 TALLOC_FREE(fname_mask);
1371                 return NT_STATUS_NO_MEMORY;
1372         }
1373
1374         *fname_dir_out = fname_dir;
1375         *fname_mask_out = fname_mask;
1376         return NT_STATUS_OK;
1377 }
1378
1379 /****************************************************************************
1380  Reply to a search.
1381  Can be called from SMBsearch, SMBffirst or SMBfunique.
1382 ****************************************************************************/
1383
1384 void reply_search(struct smb_request *req)
1385 {
1386         connection_struct *conn = req->conn;
1387         char *path = NULL;
1388         const char *mask = NULL;
1389         char *directory = NULL;
1390         struct smb_filename *smb_fname = NULL;
1391         char *fname = NULL;
1392         SMB_OFF_T size;
1393         uint32 mode;
1394         struct timespec date;
1395         uint32 dirtype;
1396         unsigned int numentries = 0;
1397         unsigned int maxentries = 0;
1398         bool finished = False;
1399         const char *p;
1400         int status_len;
1401         char status[21];
1402         int dptr_num= -1;
1403         bool check_descend = False;
1404         bool expect_close = False;
1405         NTSTATUS nt_status;
1406         bool mask_contains_wcard = False;
1407         bool allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
1408         TALLOC_CTX *ctx = talloc_tos();
1409         bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1410         struct dptr_struct *dirptr = NULL;
1411         struct smbd_server_connection *sconn = req->sconn;
1412
1413         START_PROFILE(SMBsearch);
1414
1415         if (req->wct < 2) {
1416                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1417                 goto out;
1418         }
1419
1420         if (lp_posix_pathnames()) {
1421                 reply_unknown_new(req, req->cmd);
1422                 goto out;
1423         }
1424
1425         /* If we were called as SMBffirst then we must expect close. */
1426         if(req->cmd == SMBffirst) {
1427                 expect_close = True;
1428         }
1429
1430         reply_outbuf(req, 1, 3);
1431         maxentries = SVAL(req->vwv+0, 0);
1432         dirtype = SVAL(req->vwv+1, 0);
1433         p = (const char *)req->buf + 1;
1434         p += srvstr_get_path_req_wcard(ctx, req, &path, p, STR_TERMINATE,
1435                                        &nt_status, &mask_contains_wcard);
1436         if (!NT_STATUS_IS_OK(nt_status)) {
1437                 reply_nterror(req, nt_status);
1438                 goto out;
1439         }
1440
1441         p++;
1442         status_len = SVAL(p, 0);
1443         p += 2;
1444
1445         /* dirtype &= ~FILE_ATTRIBUTE_DIRECTORY; */
1446
1447         if (status_len == 0) {
1448                 nt_status = filename_convert(ctx, conn,
1449                                              req->flags2 & FLAGS2_DFS_PATHNAMES,
1450                                              path,
1451                                              UCF_ALWAYS_ALLOW_WCARD_LCOMP,
1452                                              &mask_contains_wcard,
1453                                              &smb_fname);
1454                 if (!NT_STATUS_IS_OK(nt_status)) {
1455                         if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
1456                                 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1457                                                 ERRSRV, ERRbadpath);
1458                                 goto out;
1459                         }
1460                         reply_nterror(req, nt_status);
1461                         goto out;
1462                 }
1463
1464                 directory = smb_fname->base_name;
1465
1466                 p = strrchr_m(directory,'/');
1467                 if ((p != NULL) && (*directory != '/')) {
1468                         mask = p + 1;
1469                         directory = talloc_strndup(ctx, directory,
1470                                                    PTR_DIFF(p, directory));
1471                 } else {
1472                         mask = directory;
1473                         directory = talloc_strdup(ctx,".");
1474                 }
1475
1476                 if (!directory) {
1477                         reply_nterror(req, NT_STATUS_NO_MEMORY);
1478                         goto out;
1479                 }
1480
1481                 memset((char *)status,'\0',21);
1482                 SCVAL(status,0,(dirtype & 0x1F));
1483
1484                 nt_status = dptr_create(conn,
1485                                         NULL, /* fsp */
1486                                         directory,
1487                                         True,
1488                                         expect_close,
1489                                         req->smbpid,
1490                                         mask,
1491                                         mask_contains_wcard,
1492                                         dirtype,
1493                                         &dirptr);
1494                 if (!NT_STATUS_IS_OK(nt_status)) {
1495                         reply_nterror(req, nt_status);
1496                         goto out;
1497                 }
1498                 dptr_num = dptr_dnum(dirptr);
1499         } else {
1500                 int status_dirtype;
1501                 const char *dirpath;
1502
1503                 memcpy(status,p,21);
1504                 status_dirtype = CVAL(status,0) & 0x1F;
1505                 if (status_dirtype != (dirtype & 0x1F)) {
1506                         dirtype = status_dirtype;
1507                 }
1508
1509                 dirptr = dptr_fetch(sconn, status+12,&dptr_num);
1510                 if (!dirptr) {
1511                         goto SearchEmpty;
1512                 }
1513                 dirpath = dptr_path(sconn, dptr_num);
1514                 directory = talloc_strdup(ctx, dirpath);
1515                 if (!directory) {
1516                         reply_nterror(req, NT_STATUS_NO_MEMORY);
1517                         goto out;
1518                 }
1519
1520                 mask = dptr_wcard(sconn, dptr_num);
1521                 if (!mask) {
1522                         goto SearchEmpty;
1523                 }
1524                 /*
1525                  * For a 'continue' search we have no string. So
1526                  * check from the initial saved string.
1527                  */
1528                 mask_contains_wcard = ms_has_wild(mask);
1529                 dirtype = dptr_attr(sconn, dptr_num);
1530         }
1531
1532         DEBUG(4,("dptr_num is %d\n",dptr_num));
1533
1534         /* Initialize per SMBsearch/SMBffirst/SMBfunique operation data */
1535         dptr_init_search_op(dirptr);
1536
1537         if ((dirtype&0x1F) == FILE_ATTRIBUTE_VOLUME) {
1538                 char buf[DIR_STRUCT_SIZE];
1539                 memcpy(buf,status,21);
1540                 if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
1541                                 0,FILE_ATTRIBUTE_VOLUME,0,!allow_long_path_components)) {
1542                         reply_nterror(req, NT_STATUS_NO_MEMORY);
1543                         goto out;
1544                 }
1545                 dptr_fill(sconn, buf+12,dptr_num);
1546                 if (dptr_zero(buf+12) && (status_len==0)) {
1547                         numentries = 1;
1548                 } else {
1549                         numentries = 0;
1550                 }
1551                 if (message_push_blob(&req->outbuf,
1552                                       data_blob_const(buf, sizeof(buf)))
1553                     == -1) {
1554                         reply_nterror(req, NT_STATUS_NO_MEMORY);
1555                         goto out;
1556                 }
1557         } else {
1558                 unsigned int i;
1559                 maxentries = MIN(
1560                         maxentries,
1561                         ((BUFFER_SIZE -
1562                           ((uint8 *)smb_buf(req->outbuf) + 3 - req->outbuf))
1563                          /DIR_STRUCT_SIZE));
1564
1565                 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1566                         directory,lp_dontdescend(SNUM(conn))));
1567                 if (in_list(directory, lp_dontdescend(SNUM(conn)),True)) {
1568                         check_descend = True;
1569                 }
1570
1571                 for (i=numentries;(i<maxentries) && !finished;i++) {
1572                         finished = !get_dir_entry(ctx,
1573                                                   dirptr,
1574                                                   mask,
1575                                                   dirtype,
1576                                                   &fname,
1577                                                   &size,
1578                                                   &mode,
1579                                                   &date,
1580                                                   check_descend,
1581                                                   ask_sharemode);
1582                         if (!finished) {
1583                                 char buf[DIR_STRUCT_SIZE];
1584                                 memcpy(buf,status,21);
1585                                 if (!make_dir_struct(ctx,
1586                                                 buf,
1587                                                 mask,
1588                                                 fname,
1589                                                 size,
1590                                                 mode,
1591                                                 convert_timespec_to_time_t(date),
1592                                                 !allow_long_path_components)) {
1593                                         reply_nterror(req, NT_STATUS_NO_MEMORY);
1594                                         goto out;
1595                                 }
1596                                 if (!dptr_fill(sconn, buf+12,dptr_num)) {
1597                                         break;
1598                                 }
1599                                 if (message_push_blob(&req->outbuf,
1600                                                       data_blob_const(buf, sizeof(buf)))
1601                                     == -1) {
1602                                         reply_nterror(req, NT_STATUS_NO_MEMORY);
1603                                         goto out;
1604                                 }
1605                                 numentries++;
1606                         }
1607                 }
1608         }
1609
1610   SearchEmpty:
1611
1612         /* If we were called as SMBffirst with smb_search_id == NULL
1613                 and no entries were found then return error and close dirptr 
1614                 (X/Open spec) */
1615
1616         if (numentries == 0) {
1617                 dptr_close(sconn, &dptr_num);
1618         } else if(expect_close && status_len == 0) {
1619                 /* Close the dptr - we know it's gone */
1620                 dptr_close(sconn, &dptr_num);
1621         }
1622
1623         /* If we were called as SMBfunique, then we can close the dirptr now ! */
1624         if(dptr_num >= 0 && req->cmd == SMBfunique) {
1625                 dptr_close(sconn, &dptr_num);
1626         }
1627
1628         if ((numentries == 0) && !mask_contains_wcard) {
1629                 reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
1630                 goto out;
1631         }
1632
1633         SSVAL(req->outbuf,smb_vwv0,numentries);
1634         SSVAL(req->outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
1635         SCVAL(smb_buf(req->outbuf),0,5);
1636         SSVAL(smb_buf(req->outbuf),1,numentries*DIR_STRUCT_SIZE);
1637
1638         /* The replies here are never long name. */
1639         SSVAL(req->outbuf, smb_flg2,
1640               SVAL(req->outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
1641         if (!allow_long_path_components) {
1642                 SSVAL(req->outbuf, smb_flg2,
1643                       SVAL(req->outbuf, smb_flg2)
1644                       & (~FLAGS2_LONG_PATH_COMPONENTS));
1645         }
1646
1647         /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
1648         SSVAL(req->outbuf, smb_flg2,
1649               (SVAL(req->outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
1650
1651         DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n",
1652                 smb_fn_name(req->cmd),
1653                 mask,
1654                 directory,
1655                 dirtype,
1656                 numentries,
1657                 maxentries ));
1658  out:
1659         TALLOC_FREE(directory);
1660         TALLOC_FREE(smb_fname);
1661         END_PROFILE(SMBsearch);
1662         return;
1663 }
1664
1665 /****************************************************************************
1666  Reply to a fclose (stop directory search).
1667 ****************************************************************************/
1668
1669 void reply_fclose(struct smb_request *req)
1670 {
1671         int status_len;
1672         char status[21];
1673         int dptr_num= -2;
1674         const char *p;
1675         char *path = NULL;
1676         NTSTATUS err;
1677         bool path_contains_wcard = False;
1678         TALLOC_CTX *ctx = talloc_tos();
1679         struct smbd_server_connection *sconn = req->sconn;
1680
1681         START_PROFILE(SMBfclose);
1682
1683         if (lp_posix_pathnames()) {
1684                 reply_unknown_new(req, req->cmd);
1685                 END_PROFILE(SMBfclose);
1686                 return;
1687         }
1688
1689         p = (const char *)req->buf + 1;
1690         p += srvstr_get_path_req_wcard(ctx, req, &path, p, STR_TERMINATE,
1691                                        &err, &path_contains_wcard);
1692         if (!NT_STATUS_IS_OK(err)) {
1693                 reply_nterror(req, err);
1694                 END_PROFILE(SMBfclose);
1695                 return;
1696         }
1697         p++;
1698         status_len = SVAL(p,0);
1699         p += 2;
1700
1701         if (status_len == 0) {
1702                 reply_force_doserror(req, ERRSRV, ERRsrverror);
1703                 END_PROFILE(SMBfclose);
1704                 return;
1705         }
1706
1707         memcpy(status,p,21);
1708
1709         if(dptr_fetch(sconn, status+12,&dptr_num)) {
1710                 /*  Close the dptr - we know it's gone */
1711                 dptr_close(sconn, &dptr_num);
1712         }
1713
1714         reply_outbuf(req, 1, 0);
1715         SSVAL(req->outbuf,smb_vwv0,0);
1716
1717         DEBUG(3,("search close\n"));
1718
1719         END_PROFILE(SMBfclose);
1720         return;
1721 }
1722
1723 /****************************************************************************
1724  Reply to an open.
1725 ****************************************************************************/
1726
1727 void reply_open(struct smb_request *req)
1728 {
1729         connection_struct *conn = req->conn;
1730         struct smb_filename *smb_fname = NULL;
1731         char *fname = NULL;
1732         uint32 fattr=0;
1733         SMB_OFF_T size = 0;
1734         time_t mtime=0;
1735         int info;
1736         files_struct *fsp;
1737         int oplock_request;
1738         int deny_mode;
1739         uint32 dos_attr;
1740         uint32 access_mask;
1741         uint32 share_mode;
1742         uint32 create_disposition;
1743         uint32 create_options = 0;
1744         uint32_t private_flags = 0;
1745         NTSTATUS status;
1746         bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
1747         TALLOC_CTX *ctx = talloc_tos();
1748
1749         START_PROFILE(SMBopen);
1750
1751         if (req->wct < 2) {
1752                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1753                 goto out;
1754         }
1755
1756         oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1757         deny_mode = SVAL(req->vwv+0, 0);
1758         dos_attr = SVAL(req->vwv+1, 0);
1759
1760         srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf+1,
1761                             STR_TERMINATE, &status);
1762         if (!NT_STATUS_IS_OK(status)) {
1763                 reply_nterror(req, status);
1764                 goto out;
1765         }
1766
1767         status = filename_convert(ctx,
1768                                 conn,
1769                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
1770                                 fname,
1771                                 0,
1772                                 NULL,
1773                                 &smb_fname);
1774         if (!NT_STATUS_IS_OK(status)) {
1775                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1776                         reply_botherror(req,
1777                                         NT_STATUS_PATH_NOT_COVERED,
1778                                         ERRSRV, ERRbadpath);
1779                         goto out;
1780                 }
1781                 reply_nterror(req, status);
1782                 goto out;
1783         }
1784
1785         if (!map_open_params_to_ntcreate(smb_fname, deny_mode,
1786                                          OPENX_FILE_EXISTS_OPEN, &access_mask,
1787                                          &share_mode, &create_disposition,
1788                                          &create_options, &private_flags)) {
1789                 reply_force_doserror(req, ERRDOS, ERRbadaccess);
1790                 goto out;
1791         }
1792
1793         status = SMB_VFS_CREATE_FILE(
1794                 conn,                                   /* conn */
1795                 req,                                    /* req */
1796                 0,                                      /* root_dir_fid */
1797                 smb_fname,                              /* fname */
1798                 access_mask,                            /* access_mask */
1799                 share_mode,                             /* share_access */
1800                 create_disposition,                     /* create_disposition*/
1801                 create_options,                         /* create_options */
1802                 dos_attr,                               /* file_attributes */
1803                 oplock_request,                         /* oplock_request */
1804                 0,                                      /* allocation_size */
1805                 private_flags,
1806                 NULL,                                   /* sd */
1807                 NULL,                                   /* ea_list */
1808                 &fsp,                                   /* result */
1809                 &info);                                 /* pinfo */
1810
1811         if (!NT_STATUS_IS_OK(status)) {
1812                 if (open_was_deferred(req->mid)) {
1813                         /* We have re-scheduled this call. */
1814                         goto out;
1815                 }
1816                 reply_openerror(req, status);
1817                 goto out;
1818         }
1819
1820         size = smb_fname->st.st_ex_size;
1821         fattr = dos_mode(conn, smb_fname);
1822
1823         /* Deal with other possible opens having a modified
1824            write time. JRA. */
1825         if (ask_sharemode) {
1826                 struct timespec write_time_ts;
1827
1828                 ZERO_STRUCT(write_time_ts);
1829                 get_file_infos(fsp->file_id, 0, NULL, &write_time_ts);
1830                 if (!null_timespec(write_time_ts)) {
1831                         update_stat_ex_mtime(&smb_fname->st, write_time_ts);
1832                 }
1833         }
1834
1835         mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1836
1837         if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
1838                 DEBUG(3,("attempt to open a directory %s\n",
1839                          fsp_str_dbg(fsp)));
1840                 close_file(req, fsp, ERROR_CLOSE);
1841                 reply_botherror(req, NT_STATUS_ACCESS_DENIED,
1842                         ERRDOS, ERRnoaccess);
1843                 goto out;
1844         }
1845
1846         reply_outbuf(req, 7, 0);
1847         SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
1848         SSVAL(req->outbuf,smb_vwv1,fattr);
1849         if(lp_dos_filetime_resolution(SNUM(conn)) ) {
1850                 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime & ~1);
1851         } else {
1852                 srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime);
1853         }
1854         SIVAL(req->outbuf,smb_vwv4,(uint32)size);
1855         SSVAL(req->outbuf,smb_vwv6,deny_mode);
1856
1857         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1858                 SCVAL(req->outbuf,smb_flg,
1859                       CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1860         }
1861
1862         if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1863                 SCVAL(req->outbuf,smb_flg,
1864                       CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
1865         }
1866  out:
1867         TALLOC_FREE(smb_fname);
1868         END_PROFILE(SMBopen);
1869         return;
1870 }
1871
1872 /****************************************************************************
1873  Reply to an open and X.
1874 ****************************************************************************/
1875
1876 void reply_open_and_X(struct smb_request *req)
1877 {
1878         connection_struct *conn = req->conn;
1879         struct smb_filename *smb_fname = NULL;
1880         char *fname = NULL;
1881         uint16 open_flags;
1882         int deny_mode;
1883         uint32 smb_attr;
1884         /* Breakout the oplock request bits so we can set the
1885                 reply bits separately. */
1886         int ex_oplock_request;
1887         int core_oplock_request;
1888         int oplock_request;
1889 #if 0
1890         int smb_sattr = SVAL(req->vwv+4, 0);
1891         uint32 smb_time = make_unix_date3(req->vwv+6);
1892 #endif
1893         int smb_ofun;
1894         uint32 fattr=0;
1895         int mtime=0;
1896         int smb_action = 0;
1897         files_struct *fsp;
1898         NTSTATUS status;
1899         uint64_t allocation_size;
1900         ssize_t retval = -1;
1901         uint32 access_mask;
1902         uint32 share_mode;
1903         uint32 create_disposition;
1904         uint32 create_options = 0;
1905         uint32_t private_flags = 0;
1906         TALLOC_CTX *ctx = talloc_tos();
1907
1908         START_PROFILE(SMBopenX);
1909
1910         if (req->wct < 15) {
1911                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1912                 goto out;
1913         }
1914
1915         open_flags = SVAL(req->vwv+2, 0);
1916         deny_mode = SVAL(req->vwv+3, 0);
1917         smb_attr = SVAL(req->vwv+5, 0);
1918         ex_oplock_request = EXTENDED_OPLOCK_REQUEST(req->inbuf);
1919         core_oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
1920         oplock_request = ex_oplock_request | core_oplock_request;
1921         smb_ofun = SVAL(req->vwv+8, 0);
1922         allocation_size = (uint64_t)IVAL(req->vwv+9, 0);
1923
1924         /* If it's an IPC, pass off the pipe handler. */
1925         if (IS_IPC(conn)) {
1926                 if (lp_nt_pipe_support()) {
1927                         reply_open_pipe_and_X(conn, req);
1928                 } else {
1929                         reply_nterror(req, NT_STATUS_NETWORK_ACCESS_DENIED);
1930                 }
1931                 goto out;
1932         }
1933
1934         /* XXXX we need to handle passed times, sattr and flags */
1935         srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf,
1936                         STR_TERMINATE, &status);
1937         if (!NT_STATUS_IS_OK(status)) {
1938                 reply_nterror(req, status);
1939                 goto out;
1940         }
1941
1942         status = filename_convert(ctx,
1943                                 conn,
1944                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
1945                                 fname,
1946                                 0,
1947                                 NULL,
1948                                 &smb_fname);
1949         if (!NT_STATUS_IS_OK(status)) {
1950                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1951                         reply_botherror(req,
1952                                         NT_STATUS_PATH_NOT_COVERED,
1953                                         ERRSRV, ERRbadpath);
1954                         goto out;
1955                 }
1956                 reply_nterror(req, status);
1957                 goto out;
1958         }
1959
1960         if (!map_open_params_to_ntcreate(smb_fname, deny_mode, smb_ofun,
1961                                          &access_mask, &share_mode,
1962                                          &create_disposition,
1963                                          &create_options,
1964                                          &private_flags)) {
1965                 reply_force_doserror(req, ERRDOS, ERRbadaccess);
1966                 goto out;
1967         }
1968
1969         status = SMB_VFS_CREATE_FILE(
1970                 conn,                                   /* conn */
1971                 req,                                    /* req */
1972                 0,                                      /* root_dir_fid */
1973                 smb_fname,                              /* fname */
1974                 access_mask,                            /* access_mask */
1975                 share_mode,                             /* share_access */
1976                 create_disposition,                     /* create_disposition*/
1977                 create_options,                         /* create_options */
1978                 smb_attr,                               /* file_attributes */
1979                 oplock_request,                         /* oplock_request */
1980                 0,                                      /* allocation_size */
1981                 private_flags,
1982                 NULL,                                   /* sd */
1983                 NULL,                                   /* ea_list */
1984                 &fsp,                                   /* result */
1985                 &smb_action);                           /* pinfo */
1986
1987         if (!NT_STATUS_IS_OK(status)) {
1988                 if (open_was_deferred(req->mid)) {
1989                         /* We have re-scheduled this call. */
1990                         goto out;
1991                 }
1992                 reply_openerror(req, status);
1993                 goto out;
1994         }
1995
1996         /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
1997            if the file is truncated or created. */
1998         if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
1999                 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
2000                 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
2001                         close_file(req, fsp, ERROR_CLOSE);
2002                         reply_nterror(req, NT_STATUS_DISK_FULL);
2003                         goto out;
2004                 }
2005                 retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
2006                 if (retval < 0) {
2007                         close_file(req, fsp, ERROR_CLOSE);
2008                         reply_nterror(req, NT_STATUS_DISK_FULL);
2009                         goto out;
2010                 }
2011                 status = vfs_stat_fsp(fsp);
2012                 if (!NT_STATUS_IS_OK(status)) {
2013                         close_file(req, fsp, ERROR_CLOSE);
2014                         reply_nterror(req, status);
2015                         goto out;
2016                 }
2017         }
2018
2019         fattr = dos_mode(conn, fsp->fsp_name);
2020         mtime = convert_timespec_to_time_t(fsp->fsp_name->st.st_ex_mtime);
2021         if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
2022                 close_file(req, fsp, ERROR_CLOSE);
2023                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
2024                 goto out;
2025         }
2026
2027         /* If the caller set the extended oplock request bit
2028                 and we granted one (by whatever means) - set the
2029                 correct bit for extended oplock reply.
2030         */
2031
2032         if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
2033                 smb_action |= EXTENDED_OPLOCK_GRANTED;
2034         }
2035
2036         if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2037                 smb_action |= EXTENDED_OPLOCK_GRANTED;
2038         }
2039
2040         /* If the caller set the core oplock request bit
2041                 and we granted one (by whatever means) - set the
2042                 correct bit for core oplock reply.
2043         */
2044
2045         if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
2046                 reply_outbuf(req, 19, 0);
2047         } else {
2048                 reply_outbuf(req, 15, 0);
2049         }
2050
2051         if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
2052                 SCVAL(req->outbuf, smb_flg,
2053                       CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2054         }
2055
2056         if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2057                 SCVAL(req->outbuf, smb_flg,
2058                       CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2059         }
2060
2061         SSVAL(req->outbuf,smb_vwv2,fsp->fnum);
2062         SSVAL(req->outbuf,smb_vwv3,fattr);
2063         if(lp_dos_filetime_resolution(SNUM(conn)) ) {
2064                 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime & ~1);
2065         } else {
2066                 srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
2067         }
2068         SIVAL(req->outbuf,smb_vwv6,(uint32)fsp->fsp_name->st.st_ex_size);
2069         SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
2070         SSVAL(req->outbuf,smb_vwv11,smb_action);
2071
2072         if (open_flags & EXTENDED_RESPONSE_REQUIRED) {
2073                 SIVAL(req->outbuf, smb_vwv15, SEC_STD_ALL);
2074         }
2075
2076         chain_reply(req);
2077  out:
2078         TALLOC_FREE(smb_fname);
2079         END_PROFILE(SMBopenX);
2080         return;
2081 }
2082
2083 /****************************************************************************
2084  Reply to a SMBulogoffX.
2085 ****************************************************************************/
2086
2087 void reply_ulogoffX(struct smb_request *req)
2088 {
2089         struct smbd_server_connection *sconn = req->sconn;
2090         user_struct *vuser;
2091
2092         START_PROFILE(SMBulogoffX);
2093
2094         vuser = get_valid_user_struct(sconn, req->vuid);
2095
2096         if(vuser == NULL) {
2097                 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n",
2098                          req->vuid));
2099         }
2100
2101         /* in user level security we are supposed to close any files
2102                 open by this user */
2103         if ((vuser != NULL) && (lp_security() != SEC_SHARE)) {
2104                 file_close_user(sconn, req->vuid);
2105         }
2106
2107         invalidate_vuid(sconn, req->vuid);
2108
2109         reply_outbuf(req, 2, 0);
2110
2111         DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
2112
2113         END_PROFILE(SMBulogoffX);
2114         req->vuid = UID_FIELD_INVALID;
2115         chain_reply(req);
2116 }
2117
2118 /****************************************************************************
2119  Reply to a mknew or a create.
2120 ****************************************************************************/
2121
2122 void reply_mknew(struct smb_request *req)
2123 {
2124         connection_struct *conn = req->conn;
2125         struct smb_filename *smb_fname = NULL;
2126         char *fname = NULL;
2127         uint32 fattr = 0;
2128         struct smb_file_time ft;
2129         files_struct *fsp;
2130         int oplock_request = 0;
2131         NTSTATUS status;
2132         uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
2133         uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2134         uint32 create_disposition;
2135         uint32 create_options = 0;
2136         TALLOC_CTX *ctx = talloc_tos();
2137
2138         START_PROFILE(SMBcreate);
2139         ZERO_STRUCT(ft);
2140
2141         if (req->wct < 3) {
2142                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2143                 goto out;
2144         }
2145
2146         fattr = SVAL(req->vwv+0, 0);
2147         oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
2148
2149         /* mtime. */
2150         ft.mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1));
2151
2152         srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf + 1,
2153                             STR_TERMINATE, &status);
2154         if (!NT_STATUS_IS_OK(status)) {
2155                 reply_nterror(req, status);
2156                 goto out;
2157         }
2158
2159         status = filename_convert(ctx,
2160                                 conn,
2161                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
2162                                 fname,
2163                                 0,
2164                                 NULL,
2165                                 &smb_fname);
2166         if (!NT_STATUS_IS_OK(status)) {
2167                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2168                         reply_botherror(req,
2169                                         NT_STATUS_PATH_NOT_COVERED,
2170                                         ERRSRV, ERRbadpath);
2171                         goto out;
2172                 }
2173                 reply_nterror(req, status);
2174                 goto out;
2175         }
2176
2177         if (fattr & FILE_ATTRIBUTE_VOLUME) {
2178                 DEBUG(0,("Attempt to create file (%s) with volid set - "
2179                          "please report this\n",
2180                          smb_fname_str_dbg(smb_fname)));
2181         }
2182
2183         if(req->cmd == SMBmknew) {
2184                 /* We should fail if file exists. */
2185                 create_disposition = FILE_CREATE;
2186         } else {
2187                 /* Create if file doesn't exist, truncate if it does. */
2188                 create_disposition = FILE_OVERWRITE_IF;
2189         }
2190
2191         status = SMB_VFS_CREATE_FILE(
2192                 conn,                                   /* conn */
2193                 req,                                    /* req */
2194                 0,                                      /* root_dir_fid */
2195                 smb_fname,                              /* fname */
2196                 access_mask,                            /* access_mask */
2197                 share_mode,                             /* share_access */
2198                 create_disposition,                     /* create_disposition*/
2199                 create_options,                         /* create_options */
2200                 fattr,                                  /* file_attributes */
2201                 oplock_request,                         /* oplock_request */
2202                 0,                                      /* allocation_size */
2203                 0,                                      /* private_flags */
2204                 NULL,                                   /* sd */
2205                 NULL,                                   /* ea_list */
2206                 &fsp,                                   /* result */
2207                 NULL);                                  /* pinfo */
2208
2209         if (!NT_STATUS_IS_OK(status)) {
2210                 if (open_was_deferred(req->mid)) {
2211                         /* We have re-scheduled this call. */
2212                         goto out;
2213                 }
2214                 reply_openerror(req, status);
2215                 goto out;
2216         }
2217
2218         ft.atime = smb_fname->st.st_ex_atime; /* atime. */
2219         status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
2220         if (!NT_STATUS_IS_OK(status)) {
2221                 END_PROFILE(SMBcreate);
2222                 goto out;
2223         }
2224
2225         reply_outbuf(req, 1, 0);
2226         SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2227
2228         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2229                 SCVAL(req->outbuf,smb_flg,
2230                                 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2231         }
2232
2233         if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2234                 SCVAL(req->outbuf,smb_flg,
2235                                 CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2236         }
2237
2238         DEBUG(2, ("reply_mknew: file %s\n", smb_fname_str_dbg(smb_fname)));
2239         DEBUG(3, ("reply_mknew %s fd=%d dmode=0x%x\n",
2240                   smb_fname_str_dbg(smb_fname), fsp->fh->fd,
2241                   (unsigned int)fattr));
2242
2243  out:
2244         TALLOC_FREE(smb_fname);
2245         END_PROFILE(SMBcreate);
2246         return;
2247 }
2248
2249 /****************************************************************************
2250  Reply to a create temporary file.
2251 ****************************************************************************/
2252
2253 void reply_ctemp(struct smb_request *req)
2254 {
2255         connection_struct *conn = req->conn;
2256         struct smb_filename *smb_fname = NULL;
2257         char *fname = NULL;
2258         uint32 fattr;
2259         files_struct *fsp;
2260         int oplock_request;
2261         int tmpfd;
2262         char *s;
2263         NTSTATUS status;
2264         TALLOC_CTX *ctx = talloc_tos();
2265
2266         START_PROFILE(SMBctemp);
2267
2268         if (req->wct < 3) {
2269                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2270                 goto out;
2271         }
2272
2273         fattr = SVAL(req->vwv+0, 0);
2274         oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
2275
2276         srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf+1,
2277                             STR_TERMINATE, &status);
2278         if (!NT_STATUS_IS_OK(status)) {
2279                 reply_nterror(req, status);
2280                 goto out;
2281         }
2282         if (*fname) {
2283                 fname = talloc_asprintf(ctx,
2284                                 "%s/TMXXXXXX",
2285                                 fname);
2286         } else {
2287                 fname = talloc_strdup(ctx, "TMXXXXXX");
2288         }
2289
2290         if (!fname) {
2291                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2292                 goto out;
2293         }
2294
2295         status = filename_convert(ctx, conn,
2296                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
2297                                 fname,
2298                                 0,
2299                                 NULL,
2300                                 &smb_fname);
2301         if (!NT_STATUS_IS_OK(status)) {
2302                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2303                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2304                                         ERRSRV, ERRbadpath);
2305                         goto out;
2306                 }
2307                 reply_nterror(req, status);
2308                 goto out;
2309         }
2310
2311         tmpfd = mkstemp(smb_fname->base_name);
2312         if (tmpfd == -1) {
2313                 reply_nterror(req, map_nt_error_from_unix(errno));
2314                 goto out;
2315         }
2316
2317         SMB_VFS_STAT(conn, smb_fname);
2318
2319         /* We should fail if file does not exist. */
2320         status = SMB_VFS_CREATE_FILE(
2321                 conn,                                   /* conn */
2322                 req,                                    /* req */
2323                 0,                                      /* root_dir_fid */
2324                 smb_fname,                              /* fname */
2325                 FILE_GENERIC_READ | FILE_GENERIC_WRITE, /* access_mask */
2326                 FILE_SHARE_READ | FILE_SHARE_WRITE,     /* share_access */
2327                 FILE_OPEN,                              /* create_disposition*/
2328                 0,                                      /* create_options */
2329                 fattr,                                  /* file_attributes */
2330                 oplock_request,                         /* oplock_request */
2331                 0,                                      /* allocation_size */
2332                 0,                                      /* private_flags */
2333                 NULL,                                   /* sd */
2334                 NULL,                                   /* ea_list */
2335                 &fsp,                                   /* result */
2336                 NULL);                                  /* pinfo */
2337
2338         /* close fd from mkstemp() */
2339         close(tmpfd);
2340
2341         if (!NT_STATUS_IS_OK(status)) {
2342                 if (open_was_deferred(req->mid)) {
2343                         /* We have re-scheduled this call. */
2344                         goto out;
2345                 }
2346                 reply_openerror(req, status);
2347                 goto out;
2348         }
2349
2350         reply_outbuf(req, 1, 0);
2351         SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
2352
2353         /* the returned filename is relative to the directory */
2354         s = strrchr_m(fsp->fsp_name->base_name, '/');
2355         if (!s) {
2356                 s = fsp->fsp_name->base_name;
2357         } else {
2358                 s++;
2359         }
2360
2361 #if 0
2362         /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
2363            thing in the byte section. JRA */
2364         SSVALS(p, 0, -1); /* what is this? not in spec */
2365 #endif
2366         if (message_push_string(&req->outbuf, s, STR_ASCII|STR_TERMINATE)
2367             == -1) {
2368                 reply_nterror(req, NT_STATUS_NO_MEMORY);
2369                 goto out;
2370         }
2371
2372         if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
2373                 SCVAL(req->outbuf, smb_flg,
2374                       CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2375         }
2376
2377         if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
2378                 SCVAL(req->outbuf, smb_flg,
2379                       CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
2380         }
2381
2382         DEBUG(2, ("reply_ctemp: created temp file %s\n", fsp_str_dbg(fsp)));
2383         DEBUG(3, ("reply_ctemp %s fd=%d umode=0%o\n", fsp_str_dbg(fsp),
2384                     fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode));
2385  out:
2386         TALLOC_FREE(smb_fname);
2387         END_PROFILE(SMBctemp);
2388         return;
2389 }
2390
2391 /*******************************************************************
2392  Check if a user is allowed to rename a file.
2393 ********************************************************************/
2394
2395 static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
2396                         uint16 dirtype)
2397 {
2398         if (!CAN_WRITE(conn)) {
2399                 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2400         }
2401
2402         if ((dirtype & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) !=
2403                         (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) {
2404                 /* Only bother to read the DOS attribute if we might deny the
2405                    rename on the grounds of attribute missmatch. */
2406                 uint32_t fmode = dos_mode(conn, fsp->fsp_name);
2407                 if ((fmode & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) {
2408                         return NT_STATUS_NO_SUCH_FILE;
2409                 }
2410         }
2411
2412         if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
2413                 if (fsp->posix_open) {
2414                         return NT_STATUS_OK;
2415                 }
2416
2417                 /* If no pathnames are open below this
2418                    directory, allow the rename. */
2419
2420                 if (file_find_subpath(fsp)) {
2421                         return NT_STATUS_ACCESS_DENIED;
2422                 }
2423                 return NT_STATUS_OK;
2424         }
2425
2426         if (fsp->access_mask & (DELETE_ACCESS|FILE_WRITE_ATTRIBUTES)) {
2427                 return NT_STATUS_OK;
2428         }
2429
2430         return NT_STATUS_ACCESS_DENIED;
2431 }
2432
2433 /*******************************************************************
2434  * unlink a file with all relevant access checks
2435  *******************************************************************/
2436
2437 static NTSTATUS do_unlink(connection_struct *conn,
2438                         struct smb_request *req,
2439                         struct smb_filename *smb_fname,
2440                         uint32 dirtype)
2441 {
2442         uint32 fattr;
2443         files_struct *fsp;
2444         uint32 dirtype_orig = dirtype;
2445         NTSTATUS status;
2446         int ret;
2447         bool posix_paths = lp_posix_pathnames();
2448
2449         DEBUG(10,("do_unlink: %s, dirtype = %d\n",
2450                   smb_fname_str_dbg(smb_fname),
2451                   dirtype));
2452
2453         if (!CAN_WRITE(conn)) {
2454                 return NT_STATUS_MEDIA_WRITE_PROTECTED;
2455         }
2456
2457         if (posix_paths) {
2458                 ret = SMB_VFS_LSTAT(conn, smb_fname);
2459         } else {
2460                 ret = SMB_VFS_STAT(conn, smb_fname);
2461         }
2462         if (ret != 0) {
2463                 return map_nt_error_from_unix(errno);
2464         }
2465
2466         fattr = dos_mode(conn, smb_fname);
2467
2468         if (dirtype & FILE_ATTRIBUTE_NORMAL) {
2469                 dirtype = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY;
2470         }
2471
2472         dirtype &= (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
2473         if (!dirtype) {
2474                 return NT_STATUS_NO_SUCH_FILE;
2475         }
2476
2477         if (!dir_check_ftype(conn, fattr, dirtype)) {
2478                 if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
2479                         return NT_STATUS_FILE_IS_A_DIRECTORY;
2480                 }
2481                 return NT_STATUS_NO_SUCH_FILE;
2482         }
2483
2484         if (dirtype_orig & 0x8000) {
2485                 /* These will never be set for POSIX. */
2486                 return NT_STATUS_NO_SUCH_FILE;
2487         }
2488
2489 #if 0
2490         if ((fattr & dirtype) & FILE_ATTRIBUTE_DIRECTORY) {
2491                 return NT_STATUS_FILE_IS_A_DIRECTORY;
2492         }
2493
2494         if ((fattr & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) {
2495                 return NT_STATUS_NO_SUCH_FILE;
2496         }
2497
2498         if (dirtype & 0xFF00) {
2499                 /* These will never be set for POSIX. */
2500                 return NT_STATUS_NO_SUCH_FILE;
2501         }
2502
2503         dirtype &= 0xFF;
2504         if (!dirtype) {
2505                 return NT_STATUS_NO_SUCH_FILE;
2506         }
2507
2508         /* Can't delete a directory. */
2509         if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
2510                 return NT_STATUS_FILE_IS_A_DIRECTORY;
2511         }
2512 #endif
2513
2514 #if 0 /* JRATEST */
2515         else if (dirtype & FILE_ATTRIBUTE_DIRECTORY) /* Asked for a directory and it isn't. */
2516                 return NT_STATUS_OBJECT_NAME_INVALID;
2517 #endif /* JRATEST */
2518
2519         /* On open checks the open itself will check the share mode, so
2520            don't do it here as we'll get it wrong. */
2521
2522         status = SMB_VFS_CREATE_FILE
2523                 (conn,                  /* conn */
2524                  req,                   /* req */
2525                  0,                     /* root_dir_fid */
2526                  smb_fname,             /* fname */
2527                  DELETE_ACCESS,         /* access_mask */
2528                  FILE_SHARE_NONE,       /* share_access */
2529                  FILE_OPEN,             /* create_disposition*/
2530                  FILE_NON_DIRECTORY_FILE, /* create_options */
2531                                         /* file_attributes */
2532                  posix_paths ? FILE_FLAG_POSIX_SEMANTICS|0777 :
2533                                 FILE_ATTRIBUTE_NORMAL,
2534                  0,                     /* oplock_request */
2535                  0,                     /* allocation_size */
2536                  0,                     /* private_flags */
2537                  NULL,                  /* sd */
2538                  NULL,                  /* ea_list */
2539                  &fsp,                  /* result */
2540                  NULL);                 /* pinfo */
2541
2542         if (!NT_STATUS_IS_OK(status)) {
2543                 DEBUG(10, ("SMB_VFS_CREATEFILE failed: %s\n",
2544                            nt_errstr(status)));
2545                 return status;
2546         }
2547
2548         status = can_set_delete_on_close(fsp, fattr);
2549         if (!NT_STATUS_IS_OK(status)) {
2550                 DEBUG(10, ("do_unlink can_set_delete_on_close for file %s - "
2551                         "(%s)\n",
2552                         smb_fname_str_dbg(smb_fname),
2553                         nt_errstr(status)));
2554                 close_file(req, fsp, NORMAL_CLOSE);
2555                 return status;
2556         }
2557
2558         /* The set is across all open files on this dev/inode pair. */
2559         if (!set_delete_on_close(fsp, True, &conn->session_info->utok)) {
2560                 close_file(req, fsp, NORMAL_CLOSE);
2561                 return NT_STATUS_ACCESS_DENIED;
2562         }
2563
2564         return close_file(req, fsp, NORMAL_CLOSE);
2565 }
2566
2567 /****************************************************************************
2568  The guts of the unlink command, split out so it may be called by the NT SMB
2569  code.
2570 ****************************************************************************/
2571
2572 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
2573                           uint32 dirtype, struct smb_filename *smb_fname,
2574                           bool has_wild)
2575 {
2576         char *fname_dir = NULL;
2577         char *fname_mask = NULL;
2578         int count=0;
2579         NTSTATUS status = NT_STATUS_OK;
2580         TALLOC_CTX *ctx = talloc_tos();
2581
2582         /* Split up the directory from the filename/mask. */
2583         status = split_fname_dir_mask(ctx, smb_fname->base_name,
2584                                       &fname_dir, &fname_mask);
2585         if (!NT_STATUS_IS_OK(status)) {
2586                 goto out;
2587         }
2588
2589         /*
2590          * We should only check the mangled cache
2591          * here if unix_convert failed. This means
2592          * that the path in 'mask' doesn't exist
2593          * on the file system and so we need to look
2594          * for a possible mangle. This patch from
2595          * Tine Smukavec <valentin.smukavec@hermes.si>.
2596          */
2597
2598         if (!VALID_STAT(smb_fname->st) &&
2599             mangle_is_mangled(fname_mask, conn->params)) {
2600                 char *new_mask = NULL;
2601                 mangle_lookup_name_from_8_3(ctx, fname_mask,
2602                                             &new_mask, conn->params);
2603                 if (new_mask) {
2604                         TALLOC_FREE(fname_mask);
2605                         fname_mask = new_mask;
2606                 }
2607         }
2608
2609         if (!has_wild) {
2610
2611                 /*
2612                  * Only one file needs to be unlinked. Append the mask back
2613                  * onto the directory.
2614                  */
2615                 TALLOC_FREE(smb_fname->base_name);
2616                 if (ISDOT(fname_dir)) {
2617                         /* Ensure we use canonical names on open. */
2618                         smb_fname->base_name = talloc_asprintf(smb_fname,
2619                                                         "%s",
2620                                                         fname_mask);
2621                 } else {
2622                         smb_fname->base_name = talloc_asprintf(smb_fname,
2623                                                         "%s/%s",
2624                                                         fname_dir,
2625                                                         fname_mask);
2626                 }
2627                 if (!smb_fname->base_name) {
2628                         status = NT_STATUS_NO_MEMORY;
2629                         goto out;
2630                 }
2631                 if (dirtype == 0) {
2632                         dirtype = FILE_ATTRIBUTE_NORMAL;
2633                 }
2634
2635                 status = check_name(conn, smb_fname->base_name);
2636                 if (!NT_STATUS_IS_OK(status)) {
2637                         goto out;
2638                 }
2639
2640                 status = do_unlink(conn, req, smb_fname, dirtype);
2641                 if (!NT_STATUS_IS_OK(status)) {
2642                         goto out;
2643                 }
2644
2645                 count++;
2646         } else {
2647                 struct smb_Dir *dir_hnd = NULL;
2648                 long offset = 0;
2649                 const char *dname = NULL;
2650                 char *talloced = NULL;
2651
2652                 if ((dirtype & SAMBA_ATTRIBUTES_MASK) == FILE_ATTRIBUTE_DIRECTORY) {
2653                         status = NT_STATUS_OBJECT_NAME_INVALID;
2654                         goto out;
2655                 }
2656
2657                 if (strequal(fname_mask,"????????.???")) {
2658                         TALLOC_FREE(fname_mask);
2659                         fname_mask = talloc_strdup(ctx, "*");
2660                         if (!fname_mask) {
2661                                 status = NT_STATUS_NO_MEMORY;
2662                                 goto out;
2663                         }
2664                 }
2665
2666                 status = check_name(conn, fname_dir);
2667                 if (!NT_STATUS_IS_OK(status)) {
2668                         goto out;
2669                 }
2670
2671                 dir_hnd = OpenDir(talloc_tos(), conn, fname_dir, fname_mask,
2672                                   dirtype);
2673                 if (dir_hnd == NULL) {
2674                         status = map_nt_error_from_unix(errno);
2675                         goto out;
2676                 }
2677
2678                 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2679                    the pattern matches against the long name, otherwise the short name 
2680                    We don't implement this yet XXXX
2681                 */
2682
2683                 status = NT_STATUS_NO_SUCH_FILE;
2684
2685                 while ((dname = ReadDirName(dir_hnd, &offset,
2686                                             &smb_fname->st, &talloced))) {
2687                         TALLOC_CTX *frame = talloc_stackframe();
2688
2689                         if (!is_visible_file(conn, fname_dir, dname,
2690                                              &smb_fname->st, true)) {
2691                                 TALLOC_FREE(frame);
2692                                 TALLOC_FREE(talloced);
2693                                 continue;
2694                         }
2695
2696                         /* Quick check for "." and ".." */
2697                         if (ISDOT(dname) || ISDOTDOT(dname)) {
2698                                 TALLOC_FREE(frame);
2699                                 TALLOC_FREE(talloced);
2700                                 continue;
2701                         }
2702
2703                         if(!mask_match(dname, fname_mask,
2704                                        conn->case_sensitive)) {
2705                                 TALLOC_FREE(frame);
2706                                 TALLOC_FREE(talloced);
2707                                 continue;
2708                         }
2709
2710                         TALLOC_FREE(smb_fname->base_name);
2711                         if (ISDOT(fname_dir)) {
2712                                 /* Ensure we use canonical names on open. */
2713                                 smb_fname->base_name =
2714                                         talloc_asprintf(smb_fname, "%s",
2715                                                 dname);
2716                         } else {
2717                                 smb_fname->base_name =
2718                                         talloc_asprintf(smb_fname, "%s/%s",
2719                                                 fname_dir, dname);
2720                         }
2721
2722                         if (!smb_fname->base_name) {
2723                                 TALLOC_FREE(dir_hnd);
2724                                 status = NT_STATUS_NO_MEMORY;
2725                                 TALLOC_FREE(frame);
2726                                 TALLOC_FREE(talloced);
2727                                 goto out;
2728                         }
2729
2730                         status = check_name(conn, smb_fname->base_name);
2731                         if (!NT_STATUS_IS_OK(status)) {
2732                                 TALLOC_FREE(dir_hnd);
2733                                 TALLOC_FREE(frame);
2734                                 TALLOC_FREE(talloced);
2735                                 goto out;
2736                         }
2737
2738                         status = do_unlink(conn, req, smb_fname, dirtype);
2739                         if (!NT_STATUS_IS_OK(status)) {
2740                                 TALLOC_FREE(frame);
2741                                 TALLOC_FREE(talloced);
2742                                 continue;
2743                         }
2744
2745                         count++;
2746                         DEBUG(3,("unlink_internals: successful unlink [%s]\n",
2747                                  smb_fname->base_name));
2748
2749                         TALLOC_FREE(frame);
2750                         TALLOC_FREE(talloced);
2751                 }
2752                 TALLOC_FREE(dir_hnd);
2753         }
2754
2755         if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
2756                 status = map_nt_error_from_unix(errno);
2757         }
2758
2759  out:
2760         TALLOC_FREE(fname_dir);
2761         TALLOC_FREE(fname_mask);
2762         return status;
2763 }
2764
2765 /****************************************************************************
2766  Reply to a unlink
2767 ****************************************************************************/
2768
2769 void reply_unlink(struct smb_request *req)
2770 {
2771         connection_struct *conn = req->conn;
2772         char *name = NULL;
2773         struct smb_filename *smb_fname = NULL;
2774         uint32 dirtype;
2775         NTSTATUS status;
2776         bool path_contains_wcard = False;
2777         TALLOC_CTX *ctx = talloc_tos();
2778
2779         START_PROFILE(SMBunlink);
2780
2781         if (req->wct < 1) {
2782                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2783                 goto out;
2784         }
2785
2786         dirtype = SVAL(req->vwv+0, 0);
2787
2788         srvstr_get_path_req_wcard(ctx, req, &name, (const char *)req->buf + 1,
2789                                   STR_TERMINATE, &status,
2790                                   &path_contains_wcard);
2791         if (!NT_STATUS_IS_OK(status)) {
2792                 reply_nterror(req, status);
2793                 goto out;
2794         }
2795
2796         status = filename_convert(ctx, conn,
2797                                   req->flags2 & FLAGS2_DFS_PATHNAMES,
2798                                   name,
2799                                   UCF_COND_ALLOW_WCARD_LCOMP,
2800                                   &path_contains_wcard,
2801                                   &smb_fname);
2802         if (!NT_STATUS_IS_OK(status)) {
2803                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
2804                         reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2805                                         ERRSRV, ERRbadpath);
2806                         goto out;
2807                 }
2808                 reply_nterror(req, status);
2809                 goto out;
2810         }
2811
2812         DEBUG(3,("reply_unlink : %s\n", smb_fname_str_dbg(smb_fname)));
2813
2814         status = unlink_internals(conn, req, dirtype, smb_fname,
2815                                   path_contains_wcard);
2816         if (!NT_STATUS_IS_OK(status)) {
2817                 if (open_was_deferred(req->mid)) {
2818                         /* We have re-scheduled this call. */
2819                         goto out;
2820                 }
2821                 reply_nterror(req, status);
2822                 goto out;
2823         }
2824
2825         reply_outbuf(req, 0, 0);
2826  out:
2827         TALLOC_FREE(smb_fname);
2828         END_PROFILE(SMBunlink);
2829         return;
2830 }
2831
2832 /****************************************************************************
2833  Fail for readbraw.
2834 ****************************************************************************/
2835
2836 static void fail_readraw(void)
2837 {
2838         const char *errstr = talloc_asprintf(talloc_tos(),
2839                         "FAIL ! reply_readbraw: socket write fail (%s)",
2840                         strerror(errno));
2841         if (!errstr) {
2842                 errstr = "";
2843         }
2844         exit_server_cleanly(errstr);
2845 }
2846
2847 /****************************************************************************
2848  Fake (read/write) sendfile. Returns -1 on read or write fail.
2849 ****************************************************************************/
2850
2851 ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread)
2852 {
2853         size_t bufsize;
2854         size_t tosend = nread;
2855         char *buf;
2856
2857         if (nread == 0) {
2858                 return 0;
2859         }
2860
2861         bufsize = MIN(nread, 65536);
2862
2863         if (!(buf = SMB_MALLOC_ARRAY(char, bufsize))) {
2864                 return -1;
2865         }
2866
2867         while (tosend > 0) {
2868                 ssize_t ret;
2869                 size_t cur_read;
2870
2871                 if (tosend > bufsize) {
2872                         cur_read = bufsize;
2873                 } else {
2874                         cur_read = tosend;
2875                 }
2876                 ret = read_file(fsp,buf,startpos,cur_read);
2877                 if (ret == -1) {
2878                         SAFE_FREE(buf);
2879                         return -1;
2880                 }
2881
2882                 /* If we had a short read, fill with zeros. */
2883                 if (ret < cur_read) {
2884                         memset(buf + ret, '\0', cur_read - ret);
2885                 }
2886
2887                 if (write_data(fsp->conn->sconn->sock, buf, cur_read)
2888                     != cur_read) {
2889                         char addr[INET6_ADDRSTRLEN];
2890                         /*
2891                          * Try and give an error message saying what
2892                          * client failed.
2893                          */
2894                         DEBUG(0, ("write_data failed for client %s. "
2895                                   "Error %s\n",
2896                                   get_peer_addr(fsp->conn->sconn->sock, addr,
2897                                                 sizeof(addr)),
2898                                   strerror(errno)));
2899                         SAFE_FREE(buf);
2900                         return -1;
2901                 }
2902                 tosend -= cur_read;
2903                 startpos += cur_read;
2904         }
2905
2906         SAFE_FREE(buf);
2907         return (ssize_t)nread;
2908 }
2909
2910 /****************************************************************************
2911  Deal with the case of sendfile reading less bytes from the file than
2912  requested. Fill with zeros (all we can do).
2913 ****************************************************************************/
2914
2915 void sendfile_short_send(files_struct *fsp,
2916                                 ssize_t nread,
2917                                 size_t headersize,
2918                                 size_t smb_maxcnt)
2919 {
2920 #define SHORT_SEND_BUFSIZE 1024
2921         if (nread < headersize) {
2922                 DEBUG(0,("sendfile_short_send: sendfile failed to send "
2923                         "header for file %s (%s). Terminating\n",
2924                         fsp_str_dbg(fsp), strerror(errno)));
2925                 exit_server_cleanly("sendfile_short_send failed");
2926         }
2927
2928         nread -= headersize;
2929
2930         if (nread < smb_maxcnt) {
2931                 char *buf = SMB_CALLOC_ARRAY(char, SHORT_SEND_BUFSIZE);
2932                 if (!buf) {
2933                         exit_server_cleanly("sendfile_short_send: "
2934                                 "malloc failed");
2935                 }
2936
2937                 DEBUG(0,("sendfile_short_send: filling truncated file %s "
2938                         "with zeros !\n", fsp_str_dbg(fsp)));
2939
2940                 while (nread < smb_maxcnt) {
2941                         /*
2942                          * We asked for the real file size and told sendfile
2943                          * to not go beyond the end of the file. But it can
2944                          * happen that in between our fstat call and the
2945                          * sendfile call the file was truncated. This is very
2946                          * bad because we have already announced the larger
2947                          * number of bytes to the client.
2948                          *
2949                          * The best we can do now is to send 0-bytes, just as
2950                          * a read from a hole in a sparse file would do.
2951                          *
2952                          * This should happen rarely enough that I don't care
2953                          * about efficiency here :-)
2954                          */
2955                         size_t to_write;
2956
2957                         to_write = MIN(SHORT_SEND_BUFSIZE, smb_maxcnt - nread);
2958                         if (write_data(fsp->conn->sconn->sock, buf, to_write)
2959                             != to_write) {
2960                                 char addr[INET6_ADDRSTRLEN];
2961                                 /*
2962                                  * Try and give an error message saying what
2963                                  * client failed.
2964                                  */
2965                                 DEBUG(0, ("write_data failed for client %s. "
2966                                           "Error %s\n",
2967                                           get_peer_addr(
2968                                                   fsp->conn->sconn->sock, addr,
2969                                                   sizeof(addr)),
2970                                           strerror(errno)));
2971                                 exit_server_cleanly("sendfile_short_send: "
2972                                                     "write_data failed");
2973                         }
2974                         nread += to_write;
2975                 }
2976                 SAFE_FREE(buf);
2977         }
2978 }
2979
2980 /****************************************************************************
2981  Return a readbraw error (4 bytes of zero).
2982 ****************************************************************************/
2983
2984 static void reply_readbraw_error(struct smbd_server_connection *sconn)
2985 {
2986         char header[4];
2987
2988         SIVAL(header,0,0);
2989
2990         smbd_lock_socket(sconn);
2991         if (write_data(sconn->sock,header,4) != 4) {
2992                 char addr[INET6_ADDRSTRLEN];
2993                 /*
2994                  * Try and give an error message saying what
2995                  * client failed.
2996                  */
2997                 DEBUG(0, ("write_data failed for client %s. "
2998                           "Error %s\n",
2999                           get_peer_addr(sconn->sock, addr, sizeof(addr)),
3000                           strerror(errno)));
3001
3002                 fail_readraw();
3003         }
3004         smbd_unlock_socket(sconn);
3005 }
3006
3007 /****************************************************************************
3008  Use sendfile in readbraw.
3009 ****************************************************************************/
3010
3011 static void send_file_readbraw(connection_struct *conn,
3012                                struct smb_request *req,
3013                                files_struct *fsp,
3014                                SMB_OFF_T startpos,
3015                                size_t nread,
3016                                ssize_t mincount)
3017 {
3018         struct smbd_server_connection *sconn = req->sconn;
3019         char *outbuf = NULL;
3020         ssize_t ret=0;
3021
3022         /*
3023          * We can only use sendfile on a non-chained packet 
3024          * but we can use on a non-oplocked file. tridge proved this
3025          * on a train in Germany :-). JRA.
3026          * reply_readbraw has already checked the length.
3027          */
3028
3029         if ( !req_is_in_chain(req) && (nread > 0) && (fsp->base_fsp == NULL) &&
3030             (fsp->wcp == NULL) &&
3031             lp_use_sendfile(SNUM(conn), req->sconn->smb1.signing_state) ) {
3032                 ssize_t sendfile_read = -1;
3033                 char header[4];
3034                 DATA_BLOB header_blob;
3035
3036                 _smb_setlen(header,nread);
3037                 header_blob = data_blob_const(header, 4);
3038
3039                 sendfile_read = SMB_VFS_SENDFILE(sconn->sock, fsp,
3040                                                  &header_blob, startpos,
3041                                                  nread);
3042                 if (sendfile_read == -1) {
3043                         /* Returning ENOSYS means no data at all was sent.
3044                          * Do this as a normal read. */
3045                         if (errno == ENOSYS) {
3046                                 goto normal_readbraw;
3047                         }
3048
3049                         /*
3050                          * Special hack for broken Linux with no working sendfile. If we
3051                          * return EINTR we sent the header but not the rest of the data.
3052                          * Fake this up by doing read/write calls.
3053                          */
3054                         if (errno == EINTR) {
3055                                 /* Ensure we don't do this again. */
3056                                 set_use_sendfile(SNUM(conn), False);
3057                                 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
3058
3059                                 if (fake_sendfile(fsp, startpos, nread) == -1) {
3060                                         DEBUG(0,("send_file_readbraw: "
3061                                                  "fake_sendfile failed for "
3062                                                  "file %s (%s).\n",
3063                                                  fsp_str_dbg(fsp),
3064                                                  strerror(errno)));
3065                                         exit_server_cleanly("send_file_readbraw fake_sendfile failed");
3066                                 }
3067                                 return;
3068                         }
3069
3070                         DEBUG(0,("send_file_readbraw: sendfile failed for "
3071                                  "file %s (%s). Terminating\n",
3072                                  fsp_str_dbg(fsp), strerror(errno)));
3073                         exit_server_cleanly("send_file_readbraw sendfile failed");
3074                 } else if (sendfile_read == 0) {
3075                         /*
3076                          * Some sendfile implementations return 0 to indicate
3077                          * that there was a short read, but nothing was
3078                          * actually written to the socket.  In this case,
3079                          * fallback to the normal read path so the header gets
3080                          * the correct byte count.
3081                          */
3082                         DEBUG(3, ("send_file_readbraw: sendfile sent zero "
3083                                   "bytes falling back to the normal read: "
3084                                   "%s\n", fsp_str_dbg(fsp)));
3085                         goto normal_readbraw;
3086                 }
3087
3088                 /* Deal with possible short send. */
3089                 if (sendfile_read != 4+nread) {
3090                         sendfile_short_send(fsp, sendfile_read, 4, nread);
3091                 }
3092                 return;
3093         }
3094
3095 normal_readbraw:
3096
3097         outbuf = talloc_array(NULL, char, nread+4);
3098         if (!outbuf) {
3099                 DEBUG(0,("send_file_readbraw: talloc_array failed for size %u.\n",
3100                         (unsigned)(nread+4)));
3101                 reply_readbraw_error(sconn);
3102                 return;
3103         }
3104
3105         if (nread > 0) {
3106                 ret = read_file(fsp,outbuf+4,startpos,nread);
3107 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
3108                 if (ret < mincount)
3109                         ret = 0;
3110 #else
3111                 if (ret < nread)
3112                         ret = 0;
3113 #endif
3114         }
3115
3116         _smb_setlen(outbuf,ret);
3117         if (write_data(sconn->sock, outbuf, 4+ret) != 4+ret) {
3118                 char addr[INET6_ADDRSTRLEN];
3119                 /*
3120                  * Try and give an error message saying what
3121                  * client failed.
3122                  */
3123                 DEBUG(0, ("write_data failed for client %s. "
3124                           "Error %s\n",
3125                           get_peer_addr(fsp->conn->sconn->sock, addr,
3126                                         sizeof(addr)),
3127                           strerror(errno)));
3128
3129                 fail_readraw();
3130         }
3131
3132         TALLOC_FREE(outbuf);
3133 }
3134
3135 /****************************************************************************
3136  Reply to a readbraw (core+ protocol).
3137 ****************************************************************************/
3138
3139 void reply_readbraw(struct smb_request *req)
3140 {
3141         connection_struct *conn = req->conn;
3142         struct smbd_server_connection *sconn = req->sconn;
3143         ssize_t maxcount,mincount;
3144         size_t nread = 0;
3145         SMB_OFF_T startpos;
3146         files_struct *fsp;
3147         struct lock_struct lock;
3148         SMB_OFF_T size = 0;
3149
3150         START_PROFILE(SMBreadbraw);
3151
3152         if (srv_is_signing_active(sconn) ||
3153             is_encrypted_packet(req->inbuf)) {
3154                 exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
3155                         "raw reads/writes are disallowed.");
3156         }
3157
3158         if (req->wct < 8) {
3159                 reply_readbraw_error(sconn);
3160                 END_PROFILE(SMBreadbraw);
3161                 return;
3162         }
3163
3164         if (sconn->smb1.echo_handler.trusted_fde) {
3165                 DEBUG(2,("SMBreadbraw rejected with NOT_SUPPORTED because of "
3166                          "'async smb echo handler = yes'\n"));
3167                 reply_readbraw_error(sconn);
3168                 END_PROFILE(SMBreadbraw);
3169                 return;
3170         }
3171
3172         /*
3173          * Special check if an oplock break has been issued
3174          * and the readraw request croses on the wire, we must
3175          * return a zero length response here.
3176          */
3177
3178         fsp = file_fsp(req, SVAL(req->vwv+0, 0));
3179
3180         /*
3181          * We have to do a check_fsp by hand here, as
3182          * we must always return 4 zero bytes on error,
3183          * not a NTSTATUS.
3184          */
3185
3186         if (!fsp || !conn || conn != fsp->conn ||
3187                         req->vuid != fsp->vuid ||
3188                         fsp->is_directory || fsp->fh->fd == -1) {
3189                 /*
3190                  * fsp could be NULL here so use the value from the packet. JRA.
3191                  */
3192                 DEBUG(3,("reply_readbraw: fnum %d not valid "
3193                         "- cache prime?\n",
3194                         (int)SVAL(req->vwv+0, 0)));
3195                 reply_readbraw_error(sconn);
3196                 END_PROFILE(SMBreadbraw);
3197                 return;
3198         }
3199
3200         /* Do a "by hand" version of CHECK_READ. */
3201         if (!(fsp->can_read ||
3202                         ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) &&
3203                                 (fsp->access_mask & FILE_EXECUTE)))) {
3204                 DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
3205                                 (int)SVAL(req->vwv+0, 0)));
3206                 reply_readbraw_error(sconn);
3207                 END_PROFILE(SMBreadbraw);
3208                 return;
3209         }
3210
3211         flush_write_cache(fsp, READRAW_FLUSH);
3212
3213         startpos = IVAL_TO_SMB_OFF_T(req->vwv+1, 0);
3214         if(req->wct == 10) {
3215                 /*
3216                  * This is a large offset (64 bit) read.
3217                  */
3218 #ifdef LARGE_SMB_OFF_T
3219
3220                 startpos |= (((SMB_OFF_T)IVAL(req->vwv+8, 0)) << 32);
3221
3222 #else /* !LARGE_SMB_OFF_T */
3223
3224                 /*
3225                  * Ensure we haven't been sent a >32 bit offset.
3226                  */
3227
3228                 if(IVAL(req->vwv+8, 0) != 0) {
3229                         DEBUG(0,("reply_readbraw: large offset "
3230                                 "(%x << 32) used and we don't support "
3231                                 "64 bit offsets.\n",
3232                         (unsigned int)IVAL(req->vwv+8, 0) ));
3233                         reply_readbraw_error(sconn);
3234                         END_PROFILE(SMBreadbraw);
3235                         return;
3236                 }
3237
3238 #endif /* LARGE_SMB_OFF_T */
3239
3240                 if(startpos < 0) {
3241                         DEBUG(0,("reply_readbraw: negative 64 bit "
3242                                 "readraw offset (%.0f) !\n",
3243                                 (double)startpos ));
3244                         reply_readbraw_error(sconn);
3245                         END_PROFILE(SMBreadbraw);
3246                         return;
3247                 }
3248         }
3249
3250         maxcount = (SVAL(req->vwv+3, 0) & 0xFFFF);
3251         mincount = (SVAL(req->vwv+4, 0) & 0xFFFF);
3252
3253