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