2 Unix SMB/Netbios implementation.
4 Main SMB reply routines
5 Copyright (C) Andrew Tridgell 1992-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 This file handles most of the reply_ calls that the server
23 makes to handle specific protocols
28 #include "rpc_client.h"
32 /* look in server.c for some explanation of these variables */
34 extern int DEBUGLEVEL
;
37 extern char magic_char
;
38 extern BOOL case_sensitive
;
39 extern BOOL case_preserve
;
40 extern BOOL short_case_preserve
;
41 extern pstring sesssetup_user
;
42 extern pstring global_myname
;
43 extern fstring global_myworkgroup
;
44 extern int global_oplock_break
;
45 uint32 global_client_caps
= 0;
46 unsigned int smb_echo_count
= 0;
48 /****************************************************************************
49 report a possible attack via the password buffer overflow bug
50 ****************************************************************************/
52 static void overflow_attack(int len
)
56 dbgtext("ERROR: Invalid password length %d.\n", len
);
57 dbgtext("Your machine may be under attack by someone ");
58 dbgtext("attempting to exploit an old bug.\n");
59 dbgtext("Attack was from IP = %s.\n", client_addr());
61 exit_server("possible attack");
65 /****************************************************************************
66 reply to an special message
67 ****************************************************************************/
69 int reply_special(char *inbuf
, char *outbuf
)
72 int msg_type
= CVAL(inbuf
, 0);
73 int msg_flags
= CVAL(inbuf
, 1);
75 extern fstring remote_machine
;
76 extern fstring local_machine
;
82 memset(outbuf
, '\0', smb_size
);
84 smb_setlen(outbuf
, 0);
86 DEBUG(20, ("NBT message\n"));
87 dump_data(20, inbuf
, smb_len(inbuf
));
91 case 0x81: /* session request */
92 CVAL(outbuf
, 0) = 0x82;
94 if (name_len(inbuf
+ 4) > 50 ||
95 name_len(inbuf
+ 4 + name_len(inbuf
+ 4)) > 50)
98 ("Invalid name length in session request\n"));
101 name_extract(inbuf
, 4, name1
);
102 name_extract(inbuf
, 4 + name_len(inbuf
+ 4), name2
);
103 DEBUG(2, ("netbios connect: name1=%s name2=%s\n",
106 fstrcpy(remote_machine
, name2
);
107 remote_machine
[15] = 0;
108 trim_string(remote_machine
, " ", " ");
109 strlower(remote_machine
);
111 fstrcpy(local_machine
, name1
);
112 len
= strlen(local_machine
);
115 name_type
= local_machine
[15];
116 local_machine
[15] = 0;
118 trim_string(local_machine
, " ", " ");
119 strlower(local_machine
);
121 if (name_type
== 'R')
123 /* We are being asked for a pathworks session ---
125 CVAL(outbuf
, 0) = 0x83;
129 add_session_user(remote_machine
);
131 reload_services(True
);
136 claim_connection(NULL
, "", MAXSTATUS
, True
);
141 case 0x89: /* session keepalive request
142 (some old clients produce this?) */
143 CVAL(outbuf
, 0) = 0x85;
147 case 0x82: /* positive session response */
148 case 0x83: /* negative session response */
149 case 0x84: /* retarget session response */
150 DEBUG(0, ("Unexpected session response\n"));
153 case 0x85: /* session keepalive */
158 DEBUG(5, ("init msg_type=0x%x msg_flags=0x%x\n",
159 msg_type
, msg_flags
));
165 /*******************************************************************
166 work out what error to give to a failed connection
167 ********************************************************************/
168 static int connection_error(char *inbuf
, char *outbuf
, int ecode
)
170 if (ecode
== ERRnoipc
)
171 return (ERROR(ERRDOS
, ERRnoipc
));
173 return (ERROR(ERRSRV
, ecode
));
178 /****************************************************************************
179 parse a share descriptor string
180 ****************************************************************************/
181 static void parse_connect(char *p
, char *service
, char *user
,
182 char *password
, int *pwlen
, char *dev
)
186 DEBUG(4, ("parsing connect string %s\n", p
));
188 p2
= strrchr(p
, '\\');
192 fstrcpy(service
, p2
+ 1);
196 fstrcpy(password
, p
);
197 *pwlen
= strlen(password
);
204 p
= strchr(service
, '%');
208 fstrcpy(user
, p
+ 1);
212 /****************************************************************************
214 ****************************************************************************/
216 int reply_tcon(connection_struct
* conn
,
217 char *inbuf
, char *outbuf
, int dum_size
, int dum_buffsize
)
219 BOOL doencrypt
= SMBENCRYPT();
225 uint16 vuid
= SVAL(inbuf
, smb_uid
);
229 *service
= *user
= *password
= *dev
= 0;
231 parse_connect(smb_buf(inbuf
) + 1, service
, user
, password
, &pwlen
,
235 * Ensure the user and password names are in UNIX codepage format.
238 dos_to_unix(user
, True
);
241 dos_to_unix(password
, True
);
244 map_nt_and_unix_username(global_myworkgroup
, user
, user
, NULL
);
246 conn
= make_connection(service
, user
, global_myworkgroup
, password
,
247 pwlen
, dev
, vuid
, &ecode
);
251 return (connection_error(inbuf
, outbuf
, ecode
));
254 outsize
= set_message(outbuf
, 2, 0, True
);
255 SSVAL(outbuf
, smb_vwv0
, max_recv
);
256 SSVAL(outbuf
, smb_vwv1
, conn
->cnum
);
257 SSVAL(outbuf
, smb_tid
, conn
->cnum
);
259 DEBUG(3, ("tcon service=%s user=%s cnum=%d\n",
260 service
, user
, conn
->cnum
));
266 /****************************************************************************
267 Reply to a tcon and X.
268 ****************************************************************************/
269 int reply_tcon_and_X(connection_struct
* conn
, char *inbuf
, char *outbuf
,
270 int length
, int bufsize
)
276 BOOL doencrypt
= SMBENCRYPT();
278 uint16 vuid
= SVAL(inbuf
, smb_uid
);
279 int passlen
= SVAL(inbuf
, smb_vwv3
);
283 *service
= *user
= *password
= *devicename
= 0;
285 /* we might have to close an old one */
286 if ((SVAL(inbuf
, smb_vwv2
) & 0x1) && conn
)
288 close_cnum(conn
, vuid
);
291 if (passlen
> MAX_PASS_LEN
)
293 overflow_attack(passlen
);
296 memcpy(password
, smb_buf(inbuf
), passlen
);
297 password
[passlen
] = 0;
298 path
= smb_buf(inbuf
) + passlen
;
302 if (strequal(password
, " "))
304 passlen
= strlen(password
);
312 p
= strchr(path
+ 2, '\\');
314 return (ERROR(ERRSRV
, ERRinvnetname
));
315 fstrcpy(service
, p
+ 1);
316 p
= strchr(service
, '%');
322 StrnCpy(devicename
, path
+ strlen(path
) + 1, 6);
323 DEBUG(4, ("Got device type %s\n", devicename
));
326 * Ensure the user and password names are in UNIX codepage format.
329 dos_to_unix(user
, True
);
332 dos_to_unix(password
, True
);
335 map_nt_and_unix_username(global_myworkgroup
, user
, user
, NULL
);
337 conn
= make_connection(service
, user
, global_myworkgroup
, password
,
338 passlen
, devicename
, vuid
, &ecode
);
341 return (connection_error(inbuf
, outbuf
, ecode
));
343 if (Protocol
< PROTOCOL_NT1
)
345 set_message(outbuf
, 2, strlen(devicename
) + 1, True
);
346 pstrcpy(smb_buf(outbuf
), devicename
);
350 char *fsname
= lp_fstype(SNUM(conn
));
352 set_message(outbuf
, 3, 3, True
);
355 pstrcpy(p
, devicename
);
356 p
= skip_string(p
, 1); /* device name */
358 p
= skip_string(p
, 1); /* filesystem type e.g NTFS */
360 set_message(outbuf
, 3, PTR_DIFF(p
, smb_buf(outbuf
)), False
);
362 /* what does setting this bit do? It is set by NT4 and
363 may affect the ability to autorun mounted cdroms */
364 SSVAL(outbuf
, smb_vwv2
, SMB_SUPPORT_SEARCH_BITS
);
366 init_dfsroot(conn
, inbuf
, outbuf
);
369 DEBUG(3, ("tconX service=%s user=%s\n", service
, user
));
371 /* set the incoming and outgoing tid to the just created one */
372 SSVAL(inbuf
, smb_tid
, conn
->cnum
);
373 SSVAL(outbuf
, smb_tid
, conn
->cnum
);
375 return chain_reply(inbuf
, outbuf
, length
, bufsize
);
379 /****************************************************************************
380 reply to an unknown type
381 ****************************************************************************/
382 int reply_unknown(char *inbuf
, char *outbuf
)
385 type
= CVAL(inbuf
, smb_com
);
387 DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
388 smb_fn_name(type
), type
, type
));
390 return (ERROR(ERRSRV
, ERRunknownsmb
));
394 /****************************************************************************
396 ****************************************************************************/
397 int reply_ioctl(connection_struct
* conn
,
398 char *inbuf
, char *outbuf
, int dum_size
, int dum_buffsize
)
400 uint16 device
= SVAL(inbuf
, smb_vwv1
);
401 uint16 function
= SVAL(inbuf
, smb_vwv2
);
402 uint32 ioctl_code
= (device
<< 16) + function
;
403 int replysize
, outsize
;
405 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
407 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code
));
411 case IOCTL_QUERY_JOB_INFO
:
415 return (ERROR(ERRSRV
, ERRnosupport
));
418 outsize
= set_message(outbuf
, 8, replysize
+ 1, True
);
419 SSVAL(outbuf
, smb_vwv1
, replysize
); /* Total data bytes returned */
420 SSVAL(outbuf
, smb_vwv5
, replysize
); /* Data bytes this buffer */
421 SSVAL(outbuf
, smb_vwv6
, 52); /* Offset to data */
422 p
= smb_buf(outbuf
) + 1; /* Allow for alignment */
426 case IOCTL_QUERY_JOB_INFO
:
427 SSVAL(p
, 0, fsp
->print_jobid
); /* Job number */
428 StrnCpy(p
+ 2, global_myname
, 15); /* Our NetBIOS name */
429 StrnCpy(p
+ 18, lp_servicename(SNUM(conn
)), 13); /* Service name */
436 /****************************************************************************
437 always return an error: it's just a matter of which one...
438 ****************************************************************************/
439 static int session_trust_account(connection_struct
* conn
,
440 char *inbuf
, char *outbuf
,
441 char *user
, char *domain
,
442 char *smb_passwd
, int smb_passlen
,
443 char *smb_nt_passwd
, int smb_nt_passlen
)
448 if (lp_security() != SEC_USER
)
451 ("session_trust_account: Trust account %s only supported with security = user\n",
453 SSVAL(outbuf
, smb_flg2
, FLAGS2_32_BIT_ERROR_CODES
);
454 return (ERROR(0, 0xc0000000 | NT_STATUS_LOGON_FAILURE
));
457 if (last_challenge(last_chal
))
459 NET_USER_INFO_3 info3
;
461 status
= check_domain_security(user
, domain
,
463 (uchar
*) smb_passwd
,
465 (uchar
*) smb_nt_passwd
,
466 smb_nt_passlen
, &info3
);
470 status
= 0xc0000000 | NT_STATUS_LOGON_FAILURE
;
475 status
= 0xc0000000 | NT_STATUS_LOGON_FAILURE
;
478 SSVAL(outbuf
, smb_flg2
, FLAGS2_32_BIT_ERROR_CODES
);
479 return ERROR(0, status
);
482 /****************************************************************************
483 Return a bad password error configured for the correct client type.
484 ****************************************************************************/
486 static int bad_password_error(char *inbuf
, char *outbuf
)
488 enum remote_arch_types ra_type
= get_remote_arch();
490 if (((ra_type
== RA_WINNT
) || (ra_type
== RA_WIN2K
)) &&
491 (global_client_caps
& (CAP_NT_SMBS
| CAP_STATUS32
)))
493 SSVAL(outbuf
, smb_flg2
, FLAGS2_32_BIT_ERROR_CODES
);
494 return (ERROR(0, 0xc0000000 | NT_STATUS_LOGON_FAILURE
));
497 return (ERROR(ERRSRV
, ERRbadpw
));
500 /****************************************************************************
501 reply to a session setup command
502 ****************************************************************************/
504 int reply_sesssetup_and_X(connection_struct
* conn
, char *inbuf
, char *outbuf
,
505 int length
, int bufsize
)
508 NET_USER_INFO_3 info3
;
512 int smb_apasslen
= 0;
514 int smb_ntpasslen
= 0;
515 pstring smb_ntpasswd
;
519 static BOOL done_sesssetup
= False
;
520 BOOL doencrypt
= SMBENCRYPT();
528 smb_bufsize
= SVAL(inbuf
, smb_vwv2
);
530 if (Protocol
< PROTOCOL_NT1
)
532 smb_apasslen
= SVAL(inbuf
, smb_vwv7
);
533 if (smb_apasslen
> MAX_PASS_LEN
)
535 overflow_attack(smb_apasslen
);
538 memcpy(smb_apasswd
, smb_buf(inbuf
), smb_apasslen
);
539 smb_apasswd
[smb_apasslen
] = 0;
540 pstrcpy(user
, smb_buf(inbuf
) + smb_apasslen
);
542 if (!doencrypt
&& (lp_security() != SEC_SERVER
))
544 smb_apasslen
= strlen(smb_apasswd
);
547 if (lp_server_ntlmv2() == True
)
550 ("NTLMv2-only accepted with NT LANMAN 1.0 and above.\n\
551 user %s attempted down-level SMB connection\n",
553 return (ERROR(ERRSRV
, ERRbadpw
));
558 uint16 passlen1
= SVAL(inbuf
, smb_vwv7
);
559 uint16 passlen2
= SVAL(inbuf
, smb_vwv8
);
560 enum remote_arch_types ra_type
= get_remote_arch();
561 char *p
= smb_buf(inbuf
);
563 if (global_client_caps
== 0)
564 global_client_caps
= IVAL(inbuf
, smb_vwv11
);
566 /* client_caps is used as final determination if client is NT or Win95.
567 This is needed to return the correct error codes in some
571 if (ra_type
== RA_WINNT
|| ra_type
== RA_WIN2K
572 || ra_type
== RA_WIN95
)
575 (global_client_caps
&
576 (CAP_NT_SMBS
| CAP_STATUS32
)))
578 set_remote_arch(RA_WIN95
);
582 if (passlen1
!= 24 && passlen2
<= 24)
585 if (passlen1
> MAX_PASS_LEN
)
587 overflow_attack(passlen1
);
590 passlen1
= MIN(passlen1
, MAX_PASS_LEN
);
591 passlen2
= MIN(passlen2
, MAX_PASS_LEN
);
595 /* both Win95 and WinNT stuff up the password
596 * lengths for non-encrypting systems. Uggh.
597 * if passlen1==24 its a win95 system, and its
598 * setting the password length incorrectly. Luckily
599 * it still works with the default code because
600 * Win95 will null terminate the password anyway
601 * if passlen1>0 and passlen2>0 then maybe its a
602 * NT box and its setting passlen2 to some random
603 * value which really stuffs things up. we need to
606 * LKCLXXXX: the random value can be random 16 bit.
607 * old test used to have ... && passlen <= 24)
608 * which of course fails most of the time.
611 if (passlen1
> 0 && passlen2
> 0 && passlen2
!= 1)
615 if (lp_restrict_anonymous())
617 /* there seems to be no reason behind the differences in MS clients formatting
618 * various info like the domain, NativeOS, and NativeLanMan fields. Win95
619 * in particular seems to have an extra null byte between the username and the
620 * domain, or the password length calculation is wrong, which throws off the
621 * string extraction routines below. This makes the value of domain be the
622 * empty string, which fails the restrict anonymous check further down.
623 * This compensates for that, and allows browsing to work in mixed NT and
624 * win95 environments even when restrict anonymous is true. AAB
626 dump_data(100, p
, 0x70);
628 ("passlen1=%d, passlen2=%d\n", passlen1
,
630 if (ra_type
== RA_WIN95
&& !passlen1
&& !passlen2
631 && p
[0] == 0 && p
[1] == 0)
634 ("restrict anonymous parameter used in a win95 environment!\n"));
636 ("client is win95 and broken passlen1 offset -- attempting fix\n"));
638 ("if win95 cilents are having difficulty browsing, you will be unable to use restrict anonymous\n"));
644 || ((lp_security() == SEC_SERVER
)
645 || (lp_security() == SEC_DOMAIN
)))
647 /* Save the lanman2 password and the NT md4 password. */
648 smb_apasslen
= passlen1
;
649 memcpy(smb_apasswd
, p
, smb_apasslen
);
650 smb_apasswd
[smb_apasslen
] = 0;
651 smb_ntpasslen
= passlen2
;
652 memcpy(smb_ntpasswd
, p
+ passlen1
, smb_ntpasslen
);
653 smb_ntpasswd
[smb_ntpasslen
] = 0;
656 * Ensure the plaintext passwords are in UNIX format.
660 dos_to_unix(smb_apasswd
, True
);
661 dos_to_unix(smb_ntpasswd
, True
);
667 /* we use the first password that they gave */
668 smb_apasslen
= passlen1
;
669 StrnCpy(smb_apasswd
, p
, smb_apasslen
);
671 * Ensure the plaintext password is in UNIX format.
673 dos_to_unix(smb_apasswd
, True
);
675 /* trim the password */
676 smb_apasslen
= strlen(smb_apasswd
);
678 /* wfwg sometimes uses a space instead of a null */
679 if (strequal(smb_apasswd
, " "))
686 if (passlen2
== 0 && smb_apasslen
== 0 && ra_type
== RA_WIN95
)
688 /* work-around for win95 NULL sessions, where NULL password is
689 actually put in the data stream before the domain name etc */
694 p
+= passlen1
+ passlen2
;
698 p
= skip_string(p
, 1);
700 * Incoming user is in DOS codepage format. Convert
703 dos_to_unix(user
, True
);
707 ("passlen: %d %d Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n",
708 passlen1
, passlen2
, domain
, skip_string(p
, 1),
712 DEBUG(3, ("sesssetupX:name=[%s]\n", user
));
715 * If name ends in $ it's a trust account.
718 if (*user
&& (user
[strlen(user
) - 1] == '$') && (smb_apasslen
== 24)
719 && (smb_ntpasslen
== 24))
721 return session_trust_account(conn
, inbuf
, outbuf
, user
,
723 smb_apasslen
, smb_ntpasswd
,
727 if (done_sesssetup
&& lp_restrict_anonymous())
729 /* tests show that even if browsing is done over
730 * already validated connections without a username
731 * and password the domain is still provided, which it
732 * wouldn't be if it was a purely anonymous connection.
733 * So, in order to restrict anonymous, we only deny
734 * connections that have no session information. If a
735 * domain has been provided, then it's not a purely
736 * anonymous connection. AAB
738 if (!*user
&& !*smb_apasswd
&& !*domain
)
741 ("restrict anonymous is True and anonymous "
742 "connection attempted. Denying access.\n"));
743 return (ERROR(ERRDOS
, ERRnoaccess
));
747 /* If no username is sent use the guest account */
750 pstrcpy(user
, lp_guestaccount(-1));
751 /* If no user and no password then set guest flag. */
752 if (*smb_apasswd
== 0)
759 * map from DOS codepage format to Unix
762 dos_to_unix(user
, True
);
765 * In share level security, only overwrite sesssetup_use if
766 * it's a non null-session share. Helps keep %U and %G
770 if ((lp_security() != SEC_SHARE
) || (*user
&& !guest
))
771 pstrcpy(sesssetup_user
, user
);
772 reload_services(True
);
775 * Save the username before mapping. We will use
776 * the original username sent to us for security=server
777 * and security=domain checking.
780 pstrcpy(orig_user
, user
);
782 map_nt_and_unix_username(domain
, user
, user
, NULL
);
784 add_session_user(user
);
787 * Check if the given username was the guest user with no password.
790 if (!guest
&& strequal(user
, lp_guestaccount(-1))
791 && (*smb_apasswd
== 0))
794 if (!guest
&& !check_hosts_equiv(user
))
797 * Check with orig_user for security=server and
801 DEBUG(10, ("Checking SMB password, user %s domain %s\n",
803 if (!password_ok(orig_user
, domain
,
804 smb_apasswd
, smb_apasslen
,
805 smb_ntpasswd
, smb_ntpasslen
, NULL
, &info3
))
807 DEBUG(0, ("SMB LM/NT Password did not match!\n"));
809 if (lp_security() >= SEC_USER
)
811 if (lp_map_to_guest() == NEVER_MAP_TO_GUEST
)
814 ("Rejecting user '%s': authentication failed\n",
816 return bad_password_error(inbuf
,
820 if (lp_map_to_guest() ==
821 MAP_TO_GUEST_ON_BAD_USER
)
823 if (Get_Pwnam(user
, True
))
826 ("Rejecting user '%s': bad password\n",
835 * ..else if lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
836 * Then always map to guest account - as done below.
840 if (*smb_apasswd
|| !Get_Pwnam(user
, True
))
841 pstrcpy(user
, lp_guestaccount(-1));
843 ("Registered username %s for guest access\n",
850 if (!Get_Pwnam(user
, True
))
852 DEBUG(3, ("No such user %s - using guest account\n", user
));
853 pstrcpy(user
, lp_guestaccount(-1));
857 if (!strequal(user
, lp_guestaccount(-1)) &&
858 lp_servicenumber(user
) < 0)
860 int homes
= lp_servicenumber(HOMES_NAME
);
861 char *home
= get_user_home_dir(user
);
862 if (homes
>= 0 && home
)
865 fstrcpy(home_dir
, home
);
866 lp_add_home(user
, homes
, home_dir
);
871 /* it's ok - setup a reply */
872 if (Protocol
< PROTOCOL_NT1
)
874 set_message(outbuf
, 3, 0, True
);
879 set_message(outbuf
, 3, 3, True
);
882 p
= skip_string(p
, 1);
883 pstrcpy(p
, "Samba ");
885 p
= skip_string(p
, 1);
886 pstrcpy(p
, global_myworkgroup
);
887 p
= skip_string(p
, 1);
888 set_message(outbuf
, 3, PTR_DIFF(p
, smb_buf(outbuf
)), False
);
889 /* perhaps grab OS version here?? */
892 /* Set the correct uid in the outgoing and incoming packets
893 We will use this on future requests to determine which
894 user we should become.
897 const struct passwd
*pw
= Get_Pwnam(user
, False
);
901 ("Username %s is invalid on this system\n",
903 return bad_password_error(inbuf
, outbuf
);
910 SSVAL(outbuf
, smb_vwv2
, 1);
912 /* register the name and uid as being validated, so further connections
913 to a uid can get through without a password, on the same VC */
915 register_vuid(getpid(), uid
, gid
, user
, sesssetup_user
, guest
,
918 SSVAL(outbuf
, smb_uid
, sess_vuid
);
919 SSVAL(inbuf
, smb_uid
, sess_vuid
);
922 max_send
= MIN(max_send
, smb_bufsize
);
924 DEBUG(6, ("Client requested max send size of %d\n", max_send
));
926 done_sesssetup
= True
;
928 return chain_reply(inbuf
, outbuf
, length
, bufsize
);
932 /****************************************************************************
934 ****************************************************************************/
935 int reply_chkpth(connection_struct
* conn
, char *inbuf
, char *outbuf
,
936 int dum_size
, int dum_buffsize
)
942 BOOL bad_path
= False
;
945 pstrcpy(name
, smb_buf(inbuf
) + 1);
947 RESOLVE_DFSPATH(name
, conn
, inbuf
, outbuf
);
949 unix_convert(name
, conn
, 0, &bad_path
, &st
);
951 mode
= SVAL(inbuf
, smb_vwv0
);
953 if (check_name(name
, conn
))
956 ok
= S_ISDIR(st
.st_mode
);
958 ok
= vfs_directory_exist(conn
, name
, NULL
);
963 /* We special case this - as when a Windows machine
964 is parsing a path is steps through the components
965 one at a time - if a component fails it expects
966 ERRbadpath, not ERRbadfile.
970 unix_ERR_class
= ERRDOS
;
971 unix_ERR_code
= ERRbadpath
;
975 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
976 if ((errno
== ENOTDIR
) && (Protocol
>= PROTOCOL_NT1
) &&
977 (get_remote_arch() == RA_WINNT
))
979 unix_ERR_class
= ERRDOS
;
980 unix_ERR_code
= ERRbaddirectory
;
984 return (UNIXERROR(ERRDOS
, ERRbadpath
));
987 outsize
= set_message(outbuf
, 0, 0, True
);
989 DEBUG(3, ("chkpth %s mode=%d\n", name
, mode
));
995 /****************************************************************************
997 ****************************************************************************/
998 int reply_getatr(connection_struct
* conn
, char *inbuf
, char *outbuf
,
999 int dum_size
, int dum_buffsize
)
1003 SMB_STRUCT_STAT sbuf
;
1008 BOOL bad_path
= False
;
1010 pstrcpy(fname
, smb_buf(inbuf
) + 1);
1012 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
1014 /* if((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) && dfs_redirect(fname,conn)) return(dfs_path_error(inbuf,outbuf));
1016 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
1017 under WfWg - weird! */
1020 mode
= aHIDDEN
| aDIR
;
1021 if (!CAN_WRITE(conn
))
1029 unix_convert(fname
, conn
, 0, &bad_path
, &sbuf
);
1030 if (check_name(fname
, conn
))
1032 if (VALID_STAT(sbuf
) || dos_stat(fname
, &sbuf
) == 0)
1034 mode
= dos_mode(conn
, fname
, &sbuf
);
1035 size
= sbuf
.st_size
;
1036 mtime
= sbuf
.st_mtime
;
1043 ("stat of %s failed (%s)\n", fname
,
1050 if ((errno
== ENOENT
) && bad_path
)
1052 unix_ERR_class
= ERRDOS
;
1053 unix_ERR_code
= ERRbadpath
;
1056 return (UNIXERROR(ERRDOS
, ERRbadfile
));
1059 outsize
= set_message(outbuf
, 10, 0, True
);
1061 SSVAL(outbuf
, smb_vwv0
, mode
);
1062 if (lp_dos_filetime_resolution(SNUM(conn
)))
1063 put_dos_date3(outbuf
, smb_vwv1
, mtime
& ~1);
1065 put_dos_date3(outbuf
, smb_vwv1
, mtime
);
1066 SIVAL(outbuf
, smb_vwv3
, (uint32
)size
);
1068 if (Protocol
>= PROTOCOL_NT1
)
1070 char *p
= strrchr(fname
, '/');
1071 uint16 flg2
= SVAL(outbuf
, smb_flg2
);
1074 if (!is_8_3(fname
, True
))
1075 SSVAL(outbuf
, smb_flg2
, flg2
| 0x40); /* IS_LONG_NAME */
1079 ("getatr name=%s mode=%d size=%d\n", fname
, mode
,
1086 /****************************************************************************
1088 ****************************************************************************/
1089 int reply_setatr(connection_struct
* conn
, char *inbuf
, char *outbuf
,
1090 int dum_size
, int dum_buffsize
)
1098 BOOL bad_path
= False
;
1100 pstrcpy(fname
, smb_buf(inbuf
) + 1);
1101 unix_convert(fname
, conn
, 0, &bad_path
, &st
);
1103 mode
= SVAL(inbuf
, smb_vwv0
);
1104 mtime
= make_unix_date3(inbuf
+ smb_vwv1
);
1106 if (VALID_STAT_OF_DIR(st
) || vfs_directory_exist(conn
, fname
, NULL
))
1108 if (check_name(fname
, conn
))
1109 ok
= (file_chmod(conn
, fname
, mode
, NULL
) == 0);
1111 ok
= set_filetime(conn
, fname
, mtime
);
1115 if ((errno
== ENOENT
) && bad_path
)
1117 unix_ERR_class
= ERRDOS
;
1118 unix_ERR_code
= ERRbadpath
;
1121 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
1124 outsize
= set_message(outbuf
, 0, 0, True
);
1126 DEBUG(3, ("setatr name=%s mode=%d\n", fname
, mode
));
1132 /****************************************************************************
1134 ****************************************************************************/
1135 int reply_dskattr(connection_struct
* conn
, char *inbuf
, char *outbuf
,
1136 int dum_size
, int dum_buffsize
)
1139 SMB_BIG_UINT dfree
, dsize
, bsize
;
1141 conn
->vfs_ops
.disk_free(".", True
, &bsize
, &dfree
, &dsize
);
1143 outsize
= set_message(outbuf
, 5, 0, True
);
1145 SSVAL(outbuf
, smb_vwv0
, dsize
);
1146 SSVAL(outbuf
, smb_vwv1
, bsize
/ 512);
1147 SSVAL(outbuf
, smb_vwv2
, 512);
1148 SSVAL(outbuf
, smb_vwv3
, dfree
);
1150 DEBUG(3, ("dskattr dfree=%d\n", (unsigned int)dfree
));
1156 /****************************************************************************
1158 Can be called from SMBsearch, SMBffirst or SMBfunique.
1159 ****************************************************************************/
1160 int reply_search(connection_struct
* conn
, char *inbuf
, char *outbuf
,
1161 int dum_size
, int dum_buffsize
)
1172 BOOL finished
= False
;
1181 BOOL check_descend
= False
;
1182 BOOL expect_close
= False
;
1183 BOOL can_open
= True
;
1184 BOOL bad_path
= False
;
1186 *mask
= *directory
= *fname
= 0;
1188 /* If we were called as SMBffirst then we must expect close. */
1189 if (CVAL(inbuf
, smb_com
) == SMBffirst
)
1190 expect_close
= True
;
1192 outsize
= set_message(outbuf
, 1, 3, True
);
1193 maxentries
= SVAL(inbuf
, smb_vwv0
);
1194 dirtype
= SVAL(inbuf
, smb_vwv1
);
1195 path
= smb_buf(inbuf
) + 1;
1196 status_len
= SVAL(smb_buf(inbuf
), 3 + strlen(path
));
1199 /* dirtype &= ~aDIR; */
1201 DEBUG(5, ("reply_search: path=%s status_len=%d\n", path
, status_len
));
1204 if (status_len
== 0)
1208 pstrcpy(directory
, smb_buf(inbuf
) + 1);
1209 pstrcpy(dir2
, smb_buf(inbuf
) + 1);
1210 unix_convert(directory
, conn
, 0, &bad_path
, NULL
);
1213 if (!check_name(directory
, conn
))
1216 p
= strrchr(dir2
, '/');
1219 pstrcpy(mask
, dir2
);
1225 pstrcpy(mask
, p
+ 1);
1228 p
= strrchr(directory
, '/');
1234 if (strlen(directory
) == 0)
1235 pstrcpy(directory
, "./");
1236 memset((char *)status
, '\0', 21);
1237 CVAL(status
, 0) = dirtype
;
1241 memcpy(status
, smb_buf(inbuf
) + 1 + strlen(path
) + 4, 21);
1242 memcpy(mask
, status
+ 1, 11);
1244 dirtype
= CVAL(status
, 0) & 0x1F;
1245 conn
->dirptr
= dptr_fetch(status
+ 12, &dptr_num
);
1248 string_set(&conn
->dirpath
, dptr_path(dptr_num
));
1249 if (!case_sensitive
)
1253 /* turn strings of spaces into a . */
1255 trim_string(mask
, NULL
, " ");
1256 if ((p
= strrchr(mask
, ' ')))
1259 fstrcpy(ext
, p
+ 1);
1261 trim_string(mask
, NULL
, " ");
1267 /* Convert the formatted mask. (This code lives in trans2.c) */
1275 if ((skip
= get_character_len(*p
)) != 0)
1281 if (*p
!= '?' && *p
!= '*' && !isdoschar(*p
))
1284 ("Invalid char [%c] in search mask?\n",
1293 if (!strchr(mask
, '.') && strlen(mask
) > 8)
1296 fstrcpy(tmp
, &mask
[8]);
1302 DEBUG(5, ("mask=%s directory=%s\n", mask
, directory
));
1306 p
= smb_buf(outbuf
) + 3;
1310 if (status_len
== 0)
1313 dptr_create(conn
, directory
, True
,
1314 expect_close
, SVAL(inbuf
,
1320 if ((errno
== ENOENT
) && bad_path
)
1322 unix_ERR_class
= ERRDOS
;
1323 unix_ERR_code
= ERRbadpath
;
1325 return (UNIXERROR(ERRDOS
, ERRnofids
));
1327 return (ERROR(ERRDOS
, ERRnofids
));
1331 DEBUG(4, ("dptr_num is %d\n", dptr_num
));
1335 if ((dirtype
& 0x1F) == aVOLID
)
1337 memcpy(p
, status
, 21);
1338 make_dir_struct(p
, "???????????",
1339 volume_label(SNUM(conn
)), 0,
1341 dptr_fill(p
+ 12, dptr_num
);
1342 if (dptr_zero(p
+ 12) && (status_len
== 0))
1346 p
+= DIR_STRUCT_SIZE
;
1350 DEBUG(8, ("dirpath=<%s> dontdescend=<%s>\n",
1352 lp_dontdescend(SNUM(conn
))));
1355 lp_dontdescend(SNUM(conn
)), True
))
1356 check_descend
= True
;
1358 for (i
= numentries
;
1359 (i
< maxentries
) && !finished
; i
++)
1362 !get_dir_entry(conn
, mask
,
1369 memcpy(p
, status
, 21);
1370 make_dir_struct(p
, mask
,
1373 dptr_fill(p
+ 12, dptr_num
);
1376 p
+= DIR_STRUCT_SIZE
;
1385 if (numentries
== 0 || !ok
)
1387 CVAL(outbuf
, smb_rcls
) = ERRDOS
;
1388 SSVAL(outbuf
, smb_err
, ERRnofiles
);
1389 dptr_close(&dptr_num
);
1392 /* If we were called as SMBffirst with smb_search_id == NULL
1393 and no entries were found then return error and close dirptr
1396 if (ok
&& expect_close
&& numentries
== 0 && status_len
== 0)
1398 CVAL(outbuf
, smb_rcls
) = ERRDOS
;
1399 SSVAL(outbuf
, smb_err
, ERRnofiles
);
1400 /* Also close the dptr - we know it's gone */
1401 dptr_close(&dptr_num
);
1404 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1405 if (dptr_num
>= 0 && CVAL(inbuf
, smb_com
) == SMBfunique
)
1406 dptr_close(&dptr_num
);
1408 SSVAL(outbuf
, smb_vwv0
, numentries
);
1409 SSVAL(outbuf
, smb_vwv1
, 3 + numentries
* DIR_STRUCT_SIZE
);
1410 CVAL(smb_buf(outbuf
), 0) = 5;
1411 SSVAL(smb_buf(outbuf
), 1, numentries
* DIR_STRUCT_SIZE
);
1413 if (Protocol
>= PROTOCOL_NT1
)
1415 uint16 flg2
= SVAL(outbuf
, smb_flg2
);
1416 SSVAL(outbuf
, smb_flg2
, flg2
| 0x40); /* IS_LONG_NAME */
1419 outsize
+= DIR_STRUCT_SIZE
* numentries
;
1420 smb_setlen(outbuf
, outsize
- 4);
1422 if ((!*directory
) && dptr_path(dptr_num
))
1423 slprintf(directory
, sizeof(directory
) - 1, "(%s)",
1424 dptr_path(dptr_num
));
1426 DEBUG(4, ("%s mask=%s path=%s dtype=%d nument=%d of %d\n",
1427 smb_fn_name(CVAL(inbuf
, smb_com
)),
1428 mask
, directory
, dirtype
, numentries
, maxentries
));
1434 /****************************************************************************
1435 reply to a fclose (stop directory search)
1436 ****************************************************************************/
1437 int reply_fclose(connection_struct
* conn
, char *inbuf
, char *outbuf
,
1438 int dum_size
, int dum_buffsize
)
1446 outsize
= set_message(outbuf
, 1, 0, True
);
1447 path
= smb_buf(inbuf
) + 1;
1448 status_len
= SVAL(smb_buf(inbuf
), 3 + strlen(path
));
1451 if (status_len
== 0)
1452 return (ERROR(ERRSRV
, ERRsrverror
));
1454 memcpy(status
, smb_buf(inbuf
) + 1 + strlen(path
) + 4, 21);
1456 if (dptr_fetch(status
+ 12, &dptr_num
))
1458 /* Close the dptr - we know it's gone */
1459 dptr_close(&dptr_num
);
1462 SSVAL(outbuf
, smb_vwv0
, 0);
1464 DEBUG(3, ("search close\n"));
1470 /****************************************************************************
1472 ****************************************************************************/
1474 int reply_open(connection_struct
* conn
, char *inbuf
, char *outbuf
,
1475 int dum_size
, int dum_buffsize
)
1485 SMB_STRUCT_STAT sbuf
;
1486 BOOL bad_path
= False
;
1488 int oplock_request
= CORE_OPLOCK_REQUEST(inbuf
);
1490 share_mode
= SVAL(inbuf
, smb_vwv0
);
1492 pstrcpy(fname
, smb_buf(inbuf
) + 1);
1494 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
1496 unix_convert(fname
, conn
, 0, &bad_path
, NULL
);
1498 unixmode
= unix_mode(conn
, aARCH
, fname
);
1501 open_file_shared(conn
, fname
, share_mode
,
1502 (FILE_FAIL_IF_NOT_EXIST
| FILE_EXISTS_OPEN
),
1503 unixmode
, oplock_request
, &rmode
, NULL
);
1507 if ((errno
== ENOENT
) && bad_path
)
1509 unix_ERR_class
= ERRDOS
;
1510 unix_ERR_code
= ERRbadpath
;
1512 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
1515 if (fsp
->conn
->vfs_ops
.fstat(fsp
->fd
, &sbuf
) != 0)
1517 close_file(fsp
, False
);
1518 return (ERROR(ERRDOS
, ERRnoaccess
));
1521 size
= sbuf
.st_size
;
1522 fmode
= dos_mode(conn
, fname
, &sbuf
);
1523 mtime
= sbuf
.st_mtime
;
1527 DEBUG(3, ("attempt to open a directory %s\n", fname
));
1528 close_file(fsp
, False
);
1529 return (ERROR(ERRDOS
, ERRnoaccess
));
1532 outsize
= set_message(outbuf
, 7, 0, True
);
1533 SSVAL(outbuf
, smb_vwv0
, fsp
->fnum
);
1534 SSVAL(outbuf
, smb_vwv1
, fmode
);
1535 if (lp_dos_filetime_resolution(SNUM(conn
)))
1536 put_dos_date3(outbuf
, smb_vwv2
, mtime
& ~1);
1538 put_dos_date3(outbuf
, smb_vwv2
, mtime
);
1539 SIVAL(outbuf
, smb_vwv4
, (uint32
)size
);
1540 SSVAL(outbuf
, smb_vwv6
, rmode
);
1542 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
)))
1544 CVAL(outbuf
, smb_flg
) |= CORE_OPLOCK_GRANTED
;
1547 if (EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
))
1548 CVAL(outbuf
, smb_flg
) |= CORE_OPLOCK_GRANTED
;
1553 /****************************************************************************
1554 reply to an open and X
1555 ****************************************************************************/
1556 int reply_open_and_X(connection_struct
* conn
, char *inbuf
, char *outbuf
,
1557 int length
, int bufsize
)
1560 int smb_mode
= SVAL(inbuf
, smb_vwv3
);
1561 int smb_attr
= SVAL(inbuf
, smb_vwv5
);
1562 /* Breakout the oplock request bits so we can set the
1563 reply bits separately. */
1564 BOOL ex_oplock_request
= EXTENDED_OPLOCK_REQUEST(inbuf
);
1565 BOOL core_oplock_request
= CORE_OPLOCK_REQUEST(inbuf
);
1566 BOOL oplock_request
= ex_oplock_request
| core_oplock_request
;
1568 int open_flags
= SVAL(inbuf
, smb_vwv2
);
1569 int smb_sattr
= SVAL(inbuf
, smb_vwv4
);
1570 uint32 smb_time
= make_unix_date3(inbuf
+ smb_vwv6
);
1572 int smb_ofun
= SVAL(inbuf
, smb_vwv8
);
1575 int fmode
= 0, mtime
= 0, rmode
= 0;
1576 SMB_STRUCT_STAT sbuf
;
1578 BOOL bad_path
= False
;
1581 /* If it's an IPC, pass off the pipe handler. */
1582 if (IS_IPC(conn
) && lp_nt_pipe_support())
1583 return reply_open_pipe_and_X(conn
, inbuf
, outbuf
, length
,
1586 /* XXXX we need to handle passed times, sattr and flags */
1588 pstrcpy(fname
, smb_buf(inbuf
));
1590 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
1592 unix_convert(fname
, conn
, 0, &bad_path
, NULL
);
1594 unixmode
= unix_mode(conn
, smb_attr
| aARCH
, fname
);
1596 fsp
= open_file_shared(conn
, fname
, smb_mode
, smb_ofun
, unixmode
,
1597 oplock_request
, &rmode
, &smb_action
);
1601 if ((errno
== ENOENT
) && bad_path
)
1603 unix_ERR_class
= ERRDOS
;
1604 unix_ERR_code
= ERRbadpath
;
1606 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
1609 if (fsp
->conn
->vfs_ops
.fstat(fsp
->fd
, &sbuf
) != 0)
1611 close_file(fsp
, False
);
1612 return (ERROR(ERRDOS
, ERRnoaccess
));
1615 size
= sbuf
.st_size
;
1616 fmode
= dos_mode(conn
, fname
, &sbuf
);
1617 mtime
= sbuf
.st_mtime
;
1620 close_file(fsp
, False
);
1621 return (ERROR(ERRDOS
, ERRnoaccess
));
1624 /* If the caller set the extended oplock request bit
1625 and we granted one (by whatever means) - set the
1626 correct bit for extended oplock reply.
1629 if (ex_oplock_request
&& lp_fake_oplocks(SNUM(conn
)))
1631 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
1634 if (ex_oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
))
1636 smb_action
|= EXTENDED_OPLOCK_GRANTED
;
1639 /* If the caller set the core oplock request bit
1640 and we granted one (by whatever means) - set the
1641 correct bit for core oplock reply.
1644 if (core_oplock_request
&& lp_fake_oplocks(SNUM(conn
)))
1646 CVAL(outbuf
, smb_flg
) |= CORE_OPLOCK_GRANTED
;
1649 if (core_oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
))
1651 CVAL(outbuf
, smb_flg
) |= CORE_OPLOCK_GRANTED
;
1654 set_message(outbuf
, 15, 0, True
);
1655 SSVAL(outbuf
, smb_vwv2
, fsp
->fnum
);
1656 SSVAL(outbuf
, smb_vwv3
, fmode
);
1657 if (lp_dos_filetime_resolution(SNUM(conn
)))
1658 put_dos_date3(outbuf
, smb_vwv4
, mtime
& ~1);
1660 put_dos_date3(outbuf
, smb_vwv4
, mtime
);
1661 SIVAL(outbuf
, smb_vwv6
, (uint32
)size
);
1662 SSVAL(outbuf
, smb_vwv8
, rmode
);
1663 SSVAL(outbuf
, smb_vwv11
, smb_action
);
1665 return chain_reply(inbuf
, outbuf
, length
, bufsize
);
1669 /****************************************************************************
1670 reply to a SMBulogoffX
1671 ****************************************************************************/
1672 int reply_ulogoffX(connection_struct
* conn
, char *inbuf
, char *outbuf
,
1673 int length
, int bufsize
)
1675 uint16 vuid
= SVAL(inbuf
, smb_uid
);
1677 user_struct
*vuser
= NULL
;
1678 key
.pid
= conn
!= NULL
? conn
->smbd_pid
: getpid();
1680 vuser
= get_valid_user_struct(&key
);
1685 ("ulogoff, vuser id %d does not map to user.\n", vuid
));
1688 /* in user level security we are supposed to close any files
1689 open by this user */
1690 if ((vuser
!= 0) && (lp_security() != SEC_SHARE
))
1692 file_close_user(vuid
);
1695 invalidate_vuid(&key
);
1697 set_message(outbuf
, 2, 0, True
);
1699 DEBUG(3, ("ulogoffX vuid=%d\n", vuid
));
1701 return chain_reply(inbuf
, outbuf
, length
, bufsize
);
1705 /****************************************************************************
1706 reply to a mknew or a create
1707 ****************************************************************************/
1708 int reply_mknew(connection_struct
* conn
, char *inbuf
, char *outbuf
,
1709 int dum_size
, int dum_buffsize
)
1717 BOOL bad_path
= False
;
1719 int oplock_request
= CORE_OPLOCK_REQUEST(inbuf
);
1721 com
= SVAL(inbuf
, smb_com
);
1723 createmode
= SVAL(inbuf
, smb_vwv0
);
1724 pstrcpy(fname
, smb_buf(inbuf
) + 1);
1726 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
1728 unix_convert(fname
, conn
, 0, &bad_path
, NULL
);
1730 if (createmode
& aVOLID
)
1733 ("Attempt to create file (%s) with volid set - please report this\n",
1737 unixmode
= unix_mode(conn
, createmode
, fname
);
1739 if (com
== SMBmknew
)
1741 /* We should fail if file exists. */
1742 ofun
= FILE_CREATE_IF_NOT_EXIST
;
1746 /* SMBcreate - Create if file doesn't exist, truncate if it does. */
1747 ofun
= FILE_CREATE_IF_NOT_EXIST
| FILE_EXISTS_TRUNCATE
;
1750 /* Open file in dos compatibility share mode. */
1752 open_file_shared(conn
, fname
,
1753 SET_DENY_MODE(DENY_FCB
) |
1754 SET_OPEN_MODE(DOS_OPEN_FCB
), ofun
, unixmode
,
1755 oplock_request
, NULL
, NULL
);
1759 if ((errno
== ENOENT
) && bad_path
)
1761 unix_ERR_class
= ERRDOS
;
1762 unix_ERR_code
= ERRbadpath
;
1764 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
1767 outsize
= set_message(outbuf
, 1, 0, True
);
1768 SSVAL(outbuf
, smb_vwv0
, fsp
->fnum
);
1770 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
)))
1772 CVAL(outbuf
, smb_flg
) |= CORE_OPLOCK_GRANTED
;
1775 if (EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
))
1776 CVAL(outbuf
, smb_flg
) |= CORE_OPLOCK_GRANTED
;
1778 DEBUG(2, ("new file %s\n", fname
));
1779 DEBUG(3, ("mknew %s fd=%d dmode=%d umode=%o\n",
1780 fname
, fsp
->fd
, createmode
, (int)unixmode
));
1786 /****************************************************************************
1787 reply to a create temporary file
1788 ****************************************************************************/
1789 int reply_ctemp(connection_struct
* conn
, char *inbuf
, char *outbuf
,
1790 int dum_size
, int dum_buffsize
)
1797 BOOL bad_path
= False
;
1799 int oplock_request
= CORE_OPLOCK_REQUEST(inbuf
);
1801 createmode
= SVAL(inbuf
, smb_vwv0
);
1802 pstrcpy(fname
, smb_buf(inbuf
) + 1);
1803 pstrcat(fname
, "/TMXXXXXX");
1805 RESOLVE_DFSPATH(fname
, conn
, inbuf
, outbuf
);
1807 unix_convert(fname
, conn
, 0, &bad_path
, NULL
);
1809 unixmode
= unix_mode(conn
, createmode
, fname
);
1811 pstrcpy(fname2
, (char *)smbd_mktemp(fname
));
1813 /* Open file in dos compatibility share mode. */
1814 /* We should fail if file exists. */
1816 open_file_shared(conn
, fname2
,
1817 SET_DENY_MODE(DENY_FCB
) |
1818 SET_OPEN_MODE(DOS_OPEN_FCB
),
1819 (FILE_CREATE_IF_NOT_EXIST
|
1820 FILE_EXISTS_FAIL
), unixmode
, oplock_request
,
1825 if ((errno
== ENOENT
) && bad_path
)
1827 unix_ERR_class
= ERRDOS
;
1828 unix_ERR_code
= ERRbadpath
;
1830 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
1833 outsize
= set_message(outbuf
, 1, 2 + strlen(fname2
), True
);
1834 SSVAL(outbuf
, smb_vwv0
, fsp
->fnum
);
1835 CVAL(smb_buf(outbuf
), 0) = 4;
1836 pstrcpy(smb_buf(outbuf
) + 1, fname2
);
1838 if (oplock_request
&& lp_fake_oplocks(SNUM(conn
)))
1840 CVAL(outbuf
, smb_flg
) |= CORE_OPLOCK_GRANTED
;
1843 if (EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
))
1844 CVAL(outbuf
, smb_flg
) |= CORE_OPLOCK_GRANTED
;
1846 DEBUG(2, ("created temp file %s\n", fname2
));
1847 DEBUG(3, ("ctemp %s fd=%d dmode=%d umode=%o\n",
1848 fname2
, fsp
->fd
, createmode
, (int)unixmode
));
1854 /*******************************************************************
1855 check if a user is allowed to delete a file
1856 ********************************************************************/
1857 static BOOL
can_delete(char *fname
, connection_struct
* conn
, int dirtype
)
1859 SMB_STRUCT_STAT sbuf
;
1862 if (!CAN_WRITE(conn
))
1865 if (conn
->vfs_ops
.lstat(dos_to_unix(fname
, False
), &sbuf
) != 0)
1867 fmode
= dos_mode(conn
, fname
, &sbuf
);
1870 if (!lp_delete_readonly(SNUM(conn
)))
1875 if ((fmode
& ~dirtype
) & (aHIDDEN
| aSYSTEM
))
1877 if (!check_file_sharing(conn
, fname
, False
))
1882 /****************************************************************************
1884 ****************************************************************************/
1885 int reply_unlink(connection_struct
* conn
, char *inbuf
, char *outbuf
,
1886 int dum_size
, int dum_buffsize
)
1895 int error
= ERRnoaccess
;
1897 BOOL exists
= False
;
1898 BOOL bad_path
= False
;
1901 *directory
= *mask
= 0;
1903 dirtype
= SVAL(inbuf
, smb_vwv0
);
1905 pstrcpy(name
, smb_buf(inbuf
) + 1);
1907 RESOLVE_DFSPATH(name
, conn
, inbuf
, outbuf
);
1909 DEBUG(3, ("reply_unlink : %s\n", name
));
1911 rc
= unix_convert(name
, conn
, 0, &bad_path
, NULL
);
1913 p
= strrchr(name
, '/');
1916 pstrcpy(directory
, "./");
1917 pstrcpy(mask
, name
);
1922 pstrcpy(directory
, name
);
1923 pstrcpy(mask
, p
+ 1);
1927 * We should only check the mangled cache
1928 * here if unix_convert failed. This means
1929 * that the path in 'mask' doesn't exist
1930 * on the file system and so we need to look
1931 * for a possible mangle. This patch from
1932 * Tine Smukavec <valentin.smukavec@hermes.si>.
1935 if (!rc
&& is_mangled(mask
))
1936 check_mangled_cache(mask
);
1938 has_wild
= strchr(mask
, '*') || strchr(mask
, '?');
1942 pstrcat(directory
, "/");
1943 pstrcat(directory
, mask
);
1944 if (can_delete(directory
, conn
, dirtype
)
1945 && !dos_unlink(directory
))
1948 exists
= vfs_file_exist(conn
, directory
, NULL
);
1952 void *dirptr
= NULL
;
1955 if (check_name(directory
, conn
))
1956 dirptr
= OpenDir(conn
, directory
, True
);
1958 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
1959 the pattern matches against the long name, otherwise the short name
1960 We don't implement this yet XXXX
1967 if (strequal(mask
, "????????.???"))
1970 while ((dname
= ReadDirName(dirptr
)))
1973 pstrcpy(fname
, dname
);
1976 (fname
, mask
, case_sensitive
,
1979 error
= ERRnoaccess
;
1980 slprintf(fname
, sizeof(fname
) - 1, "%s/%s",
1982 if (!can_delete(fname
, conn
, dirtype
))
1985 unlink(dos_to_unix(fname
, False
)))
1988 ("reply_unlink : doing unlink on %s\n",
1998 return (ERROR(ERRDOS
, error
));
2001 if ((errno
== ENOENT
) && bad_path
)
2003 unix_ERR_class
= ERRDOS
;
2004 unix_ERR_code
= ERRbadpath
;
2006 return (UNIXERROR(ERRDOS
, error
));
2010 outsize
= set_message(outbuf
, 0, 0, True
);
2016 /****************************************************************************
2017 reply to a readbraw (core+ protocol)
2018 ****************************************************************************/
2020 int reply_readbraw(connection_struct
* conn
, char *inbuf
, char *outbuf
,
2021 int dum_size
, int dum_buffsize
)
2023 size_t maxcount
, mincount
;
2026 char *header
= outbuf
;
2031 * Special check if an oplock break has been issued
2032 * and the readraw request croses on the wire, we must
2033 * return a zero length response here.
2036 if (global_oplock_break
)
2038 _smb_setlen(header
, 0);
2039 transfer_file(0, smbd_server_fd(), (SMB_OFF_T
) 0, header
, 4,
2041 DEBUG(5, ("readbraw - oplock break finished\n"));
2045 fsp
= file_fsp(inbuf
, smb_vwv0
);
2047 if (!FNUM_OK(fsp
, conn
) || !fsp
->can_read
)
2050 * fsp could be NULL here so use the value from the packet. JRA.
2053 ("fnum %d not open in readbraw - cache prime?\n",
2054 (int)SVAL(inbuf
, smb_vwv0
)));
2055 _smb_setlen(header
, 0);
2056 transfer_file(0, smbd_server_fd(), (SMB_OFF_T
) 0, header
, 4,
2061 CHECK_FSP(fsp
, conn
);
2063 flush_write_cache(fsp
, READRAW_FLUSH
);
2065 startpos
= IVAL(inbuf
, smb_vwv1
);
2066 if (CVAL(inbuf
, smb_wct
) == 10)
2069 * This is a large offset (64 bit) read.
2071 #ifdef LARGE_SMB_OFF_T
2073 startpos
|= (((SMB_OFF_T
) IVAL(inbuf
, smb_vwv8
)) << 32);
2075 #else /* !LARGE_SMB_OFF_T */
2078 * Ensure we haven't been sent a >32 bit offset.
2081 if (IVAL(inbuf
, smb_vwv8
) != 0)
2084 ("readbraw - large offset (%x << 32) used and we don't support \
2086 (unsigned int)IVAL(inbuf
, smb_vwv8
)));
2087 _smb_setlen(header
, 0);
2088 transfer_file(0, smbd_server_fd(), (SMB_OFF_T
) 0,
2093 #endif /* LARGE_SMB_OFF_T */
2098 ("readbraw - negative 64 bit readraw offset (%.0f) !\n",
2100 _smb_setlen(header
, 0);
2101 transfer_file(0, smbd_server_fd(), (SMB_OFF_T
) 0,
2106 maxcount
= (SVAL(inbuf
, smb_vwv3
) & 0xFFFF);
2107 mincount
= (SVAL(inbuf
, smb_vwv4
) & 0xFFFF);
2109 /* ensure we don't overrun the packet size */
2110 maxcount
= MIN(65535, maxcount
);
2111 maxcount
= MAX(mincount
, maxcount
);
2114 (fsp
, conn
, (SMB_BIG_UINT
) maxcount
, (SMB_BIG_UINT
) startpos
,
2117 SMB_OFF_T size
= fsp
->size
;
2118 SMB_OFF_T sizeneeded
= startpos
+ maxcount
;
2120 if (size
< sizeneeded
)
2123 if (fsp
->conn
->vfs_ops
.fstat(fsp
->fd
, &st
) == 0)
2125 if (!fsp
->can_write
)
2129 nread
= MIN(maxcount
, (size
- startpos
));
2132 if (nread
< mincount
)
2135 DEBUG(3, ("readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n",
2136 fsp
->fnum
, (double)startpos
,
2137 (int)maxcount
, (int)mincount
, (int)nread
));
2141 BOOL seek_fail
= False
;
2143 _smb_setlen(header
, nread
);
2145 #if USE_READ_PREDICTION
2146 if (!fsp
->can_write
)
2148 read_predict(fsp
, fsp
->fd
, startpos
,
2149 header
+ 4, NULL
, nread
);
2150 #endif /* USE_READ_PREDICTION */
2152 if ((nread
- predict
) > 0)
2154 if (conn
->vfs_ops
.seek(fsp
, startpos
+ predict
) == -1)
2157 ("reply_readbraw: ERROR: seek_file failed.\n"));
2165 (ssize_t
) vfs_transfer_file(-1, fsp
->fd
,
2176 if (ret
!= nread
+ 4)
2178 ("ERROR: file read failure on %s at %d for %d bytes (%d)\n",
2179 fsp
->fsp_name
, startpos
, nread
, ret
));
2181 #else /* UNSAFE_READRAW */
2182 ret
= read_file(fsp
, header
+ 4, startpos
, nread
);
2186 _smb_setlen(header
, ret
);
2187 transfer_file(0, smbd_server_fd(), 0, header
, 4 + ret
, 0);
2188 #endif /* UNSAFE_READRAW */
2190 DEBUG(5, ("readbraw finished\n"));
2195 /****************************************************************************
2196 reply to a lockread (core+ protocol)
2197 ****************************************************************************/
2198 int reply_lockread(connection_struct
* conn
, char *inbuf
, char *outbuf
,
2199 int length
, int dum_buffsiz
)
2208 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
2210 CHECK_FSP(fsp
, conn
);
2214 numtoread
= SVAL(inbuf
, smb_vwv1
);
2215 startpos
= IVAL(inbuf
, smb_vwv2
);
2217 outsize
= set_message(outbuf
, 5, 3, True
);
2218 numtoread
= MIN(BUFFER_SIZE
- outsize
, numtoread
);
2219 data
= smb_buf(outbuf
) + 3;
2222 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
2223 * protocol request that predates the read/write lock concept.
2224 * Thus instead of asking for a read lock here we need to ask
2225 * for a write lock. JRA.
2229 (fsp
, conn
, (SMB_BIG_UINT
) numtoread
, (SMB_BIG_UINT
) startpos
,
2230 WRITE_LOCK
, &eclass
, &ecode
))
2232 if ((ecode
== ERRlock
) && lp_blocking_locks(SNUM(conn
)))
2235 * A blocking lock was requested. Package up
2236 * this smb into a queued request and push it
2237 * onto the blocking lock queue.
2239 if (push_blocking_lock_request(inbuf
, length
, -1, 0))
2242 return (ERROR(eclass
, ecode
));
2245 nread
= read_file(fsp
, data
, startpos
, numtoread
);
2248 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
2251 SSVAL(outbuf
, smb_vwv0
, nread
);
2252 SSVAL(outbuf
, smb_vwv5
, nread
+ 3);
2253 SSVAL(smb_buf(outbuf
), 1, nread
);
2255 DEBUG(3, ("lockread fnum=%d num=%d nread=%d\n",
2256 fsp
->fnum
, (int)numtoread
, (int)nread
));
2262 /****************************************************************************
2264 ****************************************************************************/
2266 int reply_read(connection_struct
* conn
, char *inbuf
, char *outbuf
, int size
,
2274 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
2276 CHECK_FSP(fsp
, conn
);
2280 numtoread
= SVAL(inbuf
, smb_vwv1
);
2281 startpos
= IVAL(inbuf
, smb_vwv2
);
2283 outsize
= set_message(outbuf
, 5, 3, True
);
2284 numtoread
= MIN(BUFFER_SIZE
- outsize
, numtoread
);
2285 data
= smb_buf(outbuf
) + 3;
2288 (fsp
, conn
, (SMB_BIG_UINT
) numtoread
, (SMB_BIG_UINT
) startpos
,
2290 return (ERROR(ERRDOS
, ERRlock
));
2293 nread
= read_file(fsp
, data
, startpos
, numtoread
);
2296 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
2299 SSVAL(outbuf
, smb_vwv0
, nread
);
2300 SSVAL(outbuf
, smb_vwv5
, nread
+ 3);
2301 CVAL(smb_buf(outbuf
), 0) = 1;
2302 SSVAL(smb_buf(outbuf
), 1, nread
);
2304 DEBUG(3, ("read fnum=%d num=%d nread=%d\n",
2305 fsp
->fnum
, (int)numtoread
, (int)nread
));
2311 /****************************************************************************
2312 reply to a read and X
2313 ****************************************************************************/
2314 int reply_read_and_X(connection_struct
* conn
, char *inbuf
, char *outbuf
,
2315 int length
, int bufsize
)
2317 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv2
);
2318 SMB_OFF_T startpos
= IVAL(inbuf
, smb_vwv3
);
2319 size_t smb_maxcnt
= SVAL(inbuf
, smb_vwv5
);
2320 size_t smb_mincnt
= SVAL(inbuf
, smb_vwv6
);
2324 /* If it's an IPC, pass off the pipe handler. */
2326 return reply_pipe_read_and_X(inbuf
, outbuf
, length
, bufsize
);
2328 CHECK_FSP(fsp
, conn
);
2332 set_message(outbuf
, 12, 0, True
);
2333 data
= smb_buf(outbuf
);
2335 if (CVAL(inbuf
, smb_wct
) == 12)
2337 #ifdef LARGE_SMB_OFF_T
2339 * This is a large offset (64 bit) read.
2341 startpos
|= (((SMB_OFF_T
) IVAL(inbuf
, smb_vwv10
)) << 32);
2343 #else /* !LARGE_SMB_OFF_T */
2346 * Ensure we haven't been sent a >32 bit offset.
2349 if (IVAL(inbuf
, smb_vwv10
) != 0)
2352 ("reply_read_and_X - large offset (%x << 32) used and we don't support \
2354 (unsigned int)IVAL(inbuf
, smb_vwv10
)));
2355 return (ERROR(ERRDOS
, ERRbadaccess
));
2358 #endif /* LARGE_SMB_OFF_T */
2363 (fsp
, conn
, (SMB_BIG_UINT
) smb_maxcnt
, (SMB_BIG_UINT
) startpos
,
2365 return (ERROR(ERRDOS
, ERRlock
));
2366 nread
= read_file(fsp
, data
, startpos
, smb_maxcnt
);
2369 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
2371 SSVAL(outbuf
, smb_vwv5
, nread
);
2372 SSVAL(outbuf
, smb_vwv6
, smb_offset(data
, outbuf
));
2373 SSVAL(smb_buf(outbuf
), -2, nread
);
2375 DEBUG(3, ("readX fnum=%d min=%d max=%d nread=%d\n",
2376 fsp
->fnum
, (int)smb_mincnt
, (int)smb_maxcnt
, (int)nread
));
2378 return chain_reply(inbuf
, outbuf
, length
, bufsize
);
2381 /****************************************************************************
2382 reply to a writebraw (core+ or LANMAN1.0 protocol)
2383 ****************************************************************************/
2385 int reply_writebraw(connection_struct
* conn
, char *inbuf
, char *outbuf
,
2386 int size
, int dum_buffsize
)
2388 ssize_t nwritten
= 0;
2389 ssize_t total_written
= 0;
2390 size_t numtowrite
= 0;
2395 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
2398 CHECK_FSP(fsp
, conn
);
2402 tcount
= IVAL(inbuf
, smb_vwv1
);
2403 startpos
= IVAL(inbuf
, smb_vwv3
);
2404 write_through
= BITSETW(inbuf
+ smb_vwv7
, 0);
2406 /* We have to deal with slightly different formats depending
2407 on whether we are using the core+ or lanman1.0 protocol */
2408 if (Protocol
<= PROTOCOL_COREPLUS
)
2410 numtowrite
= SVAL(smb_buf(inbuf
), -2);
2411 data
= smb_buf(inbuf
);
2415 numtowrite
= SVAL(inbuf
, smb_vwv10
);
2416 data
= smb_base(inbuf
) + SVAL(inbuf
, smb_vwv11
);
2419 /* force the error type */
2420 CVAL(inbuf
, smb_com
) = SMBwritec
;
2421 CVAL(outbuf
, smb_com
) = SMBwritec
;
2424 (fsp
, conn
, (SMB_BIG_UINT
) tcount
, (SMB_BIG_UINT
) startpos
,
2426 return (ERROR(ERRDOS
, ERRlock
));
2429 nwritten
= write_file(fsp
, data
, startpos
, numtowrite
);
2431 DEBUG(3, ("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
2432 fsp
->fnum
, (double)startpos
, (int)numtowrite
, (int)nwritten
,
2433 (int)write_through
));
2435 if (nwritten
< numtowrite
)
2436 return (UNIXERROR(ERRHRD
, ERRdiskfull
));
2438 total_written
= nwritten
;
2440 /* Return a message to the redirector to tell it
2441 to send more bytes */
2442 CVAL(outbuf
, smb_com
) = SMBwritebraw
;
2443 SSVALS(outbuf
, smb_vwv0
, -1);
2445 set_message(outbuf
, Protocol
> PROTOCOL_COREPLUS
? 1 : 0, 0,
2447 send_smb(smbd_server_fd(), outbuf
);
2449 /* Now read the raw data into the buffer and write it */
2450 if (read_smb_length(smbd_server_fd(), inbuf
, SMB_SECONDARY_WAIT
) ==
2453 exit_server("secondary writebraw failed");
2456 /* Even though this is not an smb message, smb_len
2457 returns the generic length of an smb message */
2458 numtowrite
= smb_len(inbuf
);
2460 if (tcount
> nwritten
+ numtowrite
)
2462 DEBUG(3, ("Client overestimated the write %d %d %d\n",
2463 (int)tcount
, (int)nwritten
, (int)numtowrite
));
2466 nwritten
= vfs_transfer_file(smbd_server_fd(), NULL
, -1, fsp
,
2467 (SMB_OFF_T
) numtowrite
, NULL
, 0,
2468 startpos
+ nwritten
);
2469 total_written
+= nwritten
;
2471 /* Set up outbuf to return the correct return */
2472 outsize
= set_message(outbuf
, 1, 0, True
);
2473 CVAL(outbuf
, smb_com
) = SMBwritec
;
2474 SSVAL(outbuf
, smb_vwv0
, total_written
);
2476 if (nwritten
< (ssize_t
) numtowrite
)
2478 CVAL(outbuf
, smb_rcls
) = ERRHRD
;
2479 SSVAL(outbuf
, smb_err
, ERRdiskfull
);
2482 if ((lp_syncalways(SNUM(conn
)) || write_through
) &&
2483 lp_strict_sync(SNUM(conn
)))
2484 conn
->vfs_ops
.fsync(fsp
->fd
);
2486 DEBUG(3, ("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
2487 fsp
->fnum
, (double)startpos
, (int)numtowrite
,
2488 (int)total_written
));
2490 /* we won't return a status if write through is not selected - this
2491 follows what WfWg does */
2492 if (!write_through
&& total_written
== tcount
)
2498 /****************************************************************************
2499 reply to a writeunlock (core+)
2500 ****************************************************************************/
2502 int reply_writeunlock(connection_struct
* conn
, char *inbuf
, char *outbuf
,
2503 int size
, int dum_buffsize
)
2505 ssize_t nwritten
= -1;
2511 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
2514 CHECK_FSP(fsp
, conn
);
2518 numtowrite
= SVAL(inbuf
, smb_vwv1
);
2519 startpos
= IVAL(inbuf
, smb_vwv2
);
2520 data
= smb_buf(inbuf
) + 3;
2523 (fsp
, conn
, (SMB_BIG_UINT
) numtowrite
, (SMB_BIG_UINT
) startpos
,
2525 return (ERROR(ERRDOS
, ERRlock
));
2527 /* The special X/Open SMB protocol handling of
2528 zero length writes is *NOT* done for
2530 if (numtowrite
== 0)
2533 nwritten
= write_file(fsp
, data
, startpos
, numtowrite
);
2535 if (lp_syncalways(SNUM(conn
)))
2536 conn
->vfs_ops
.fsync(fsp
->fd
);
2538 if (((nwritten
== 0) && (numtowrite
!= 0)) || (nwritten
< 0))
2539 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
2542 (fsp
, conn
, (SMB_BIG_UINT
) numtowrite
, (SMB_BIG_UINT
) startpos
,
2544 return (ERROR(eclass
, ecode
));
2546 outsize
= set_message(outbuf
, 1, 0, True
);
2548 SSVAL(outbuf
, smb_vwv0
, nwritten
);
2550 DEBUG(3, ("writeunlock fnum=%d num=%d wrote=%d\n",
2551 fsp
->fnum
, (int)numtowrite
, (int)nwritten
));
2556 /****************************************************************************
2558 ****************************************************************************/
2559 int reply_write(connection_struct
* conn
, char *inbuf
, char *outbuf
, int size
,
2563 ssize_t nwritten
= -1;
2566 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
2569 /* If it's an IPC, pass off the pipe handler. */
2571 return reply_pipe_write(inbuf
, outbuf
, size
, dum_buffsize
);
2573 CHECK_FSP(fsp
, conn
);
2577 numtowrite
= SVAL(inbuf
, smb_vwv1
);
2578 startpos
= IVAL(inbuf
, smb_vwv2
);
2579 data
= smb_buf(inbuf
) + 3;
2582 (fsp
, conn
, (SMB_BIG_UINT
) numtowrite
, (SMB_BIG_UINT
) startpos
,
2584 return (ERROR(ERRDOS
, ERRlock
));
2586 /* X/Open SMB protocol says that if smb_vwv1 is
2587 zero then the file size should be extended or
2588 truncated to the size given in smb_vwv[2-3] */
2589 if (numtowrite
== 0)
2591 if ((nwritten
= set_filelen(fsp
->fd
, (SMB_OFF_T
) startpos
)) >= 0) /* tpot vfs */
2592 set_filelen_write_cache(fsp
, startpos
);
2595 nwritten
= write_file(fsp
, data
, startpos
, numtowrite
);
2597 if (lp_syncalways(SNUM(conn
)))
2598 conn
->vfs_ops
.fsync(fsp
->fd
);
2600 if (((nwritten
== 0) && (numtowrite
!= 0)) || (nwritten
< 0))
2601 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
2603 outsize
= set_message(outbuf
, 1, 0, True
);
2605 SSVAL(outbuf
, smb_vwv0
, nwritten
);
2607 if (nwritten
< (ssize_t
) numtowrite
)
2609 CVAL(outbuf
, smb_rcls
) = ERRHRD
;
2610 SSVAL(outbuf
, smb_err
, ERRdiskfull
);
2613 DEBUG(3, ("write fnum=%d num=%d wrote=%d\n",
2614 fsp
->fnum
, (int)numtowrite
, (int)nwritten
));
2620 /****************************************************************************
2621 reply to a write and X
2622 ****************************************************************************/
2623 int reply_write_and_X(connection_struct
* conn
, char *inbuf
, char *outbuf
,
2624 int length
, int bufsize
)
2626 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv2
);
2627 SMB_OFF_T startpos
= IVAL(inbuf
, smb_vwv3
);
2628 size_t numtowrite
= SVAL(inbuf
, smb_vwv10
);
2629 BOOL write_through
= BITSETW(inbuf
+ smb_vwv7
, 0);
2630 ssize_t nwritten
= -1;
2631 unsigned int smb_doff
= SVAL(inbuf
, smb_vwv11
);
2634 /* If it's an IPC, pass off the pipe handler. */
2636 return reply_pipe_write_and_X(inbuf
, outbuf
, length
, bufsize
);
2638 CHECK_FSP(fsp
, conn
);
2642 if(smb_doff
> smb_len(inbuf
))
2643 return(ERROR(ERRDOS
,ERRbadmem
));
2645 data
= smb_base(inbuf
) + smb_doff
;
2647 if (CVAL(inbuf
, smb_wct
) == 14)
2649 #ifdef LARGE_SMB_OFF_T
2651 * This is a large offset (64 bit) write.
2653 startpos
|= (((SMB_OFF_T
) IVAL(inbuf
, smb_vwv12
)) << 32);
2655 #else /* !LARGE_SMB_OFF_T */
2658 * Ensure we haven't been sent a >32 bit offset.
2661 if (IVAL(inbuf
, smb_vwv12
) != 0)
2664 ("reply_write_and_X - large offset (%x << 32) used and we don't support \
2666 (unsigned int)IVAL(inbuf
, smb_vwv12
)));
2667 return (ERROR(ERRDOS
, ERRbadaccess
));
2670 #endif /* LARGE_SMB_OFF_T */
2674 (fsp
, conn
, (SMB_BIG_UINT
) numtowrite
, (SMB_BIG_UINT
) startpos
,
2676 return (ERROR(ERRDOS
, ERRlock
));
2678 /* X/Open SMB protocol says that, unlike SMBwrite
2679 if the length is zero then NO truncation is
2680 done, just a write of zero. To truncate a file,
2682 if (numtowrite
== 0)
2685 nwritten
= write_file(fsp
, data
, startpos
, numtowrite
);
2687 if (((nwritten
== 0) && (numtowrite
!= 0)) || (nwritten
< 0))
2688 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
2690 set_message(outbuf
, 6, 0, True
);
2692 SSVAL(outbuf
, smb_vwv2
, nwritten
);
2694 if (nwritten
< (ssize_t
) numtowrite
)
2696 CVAL(outbuf
, smb_rcls
) = ERRHRD
;
2697 SSVAL(outbuf
, smb_err
, ERRdiskfull
);
2700 DEBUG(3, ("writeX fnum=%d num=%d wrote=%d\n",
2701 fsp
->fnum
, (int)numtowrite
, (int)nwritten
));
2703 if (lp_syncalways(SNUM(conn
)) || write_through
)
2704 conn
->vfs_ops
.fsync(fsp
->fd
);
2706 return chain_reply(inbuf
, outbuf
, length
, bufsize
);
2710 /****************************************************************************
2712 ****************************************************************************/
2714 int reply_lseek(connection_struct
* conn
, char *inbuf
, char *outbuf
, int size
,
2721 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
2723 CHECK_FSP(fsp
, conn
);
2726 flush_write_cache(fsp
, SEEK_FLUSH
);
2728 mode
= SVAL(inbuf
, smb_vwv1
) & 3;
2729 startpos
= IVALS(inbuf
, smb_vwv2
);
2747 if ((res
= conn
->vfs_ops
.lseek(fsp
->fd
, startpos
, umode
)) == -1)
2750 * Check for the special case where a seek before the start
2751 * of the file sets the offset to zero. Added in the CIFS spec,
2755 if (errno
== EINVAL
)
2757 SMB_OFF_T current_pos
= startpos
;
2759 if (umode
== SEEK_CUR
)
2764 conn
->vfs_ops
.lseek(fsp
->fd
, 0,
2767 (ERRDOS
, ERRnoaccess
));
2769 current_pos
+= startpos
;
2772 else if (umode
== SEEK_END
)
2775 SMB_STRUCT_STAT sbuf
;
2777 if (conn
->vfs_ops
.fstat(fsp
->fd
, &sbuf
) == -1)
2779 (ERRDOS
, ERRnoaccess
));
2781 current_pos
+= sbuf
.st_size
;
2784 if (current_pos
< 0)
2786 conn
->vfs_ops
.lseek(fsp
->fd
, 0,
2791 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
2796 outsize
= set_message(outbuf
, 2, 0, True
);
2797 SIVAL(outbuf
, smb_vwv0
, res
);
2799 DEBUG(3, ("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
2800 fsp
->fnum
, (double)startpos
, (double)res
, mode
));
2805 /****************************************************************************
2807 ****************************************************************************/
2809 int reply_flush(connection_struct
* conn
, char *inbuf
, char *outbuf
, int size
,
2812 int outsize
= set_message(outbuf
, 0, 0, True
);
2813 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
2817 CHECK_FSP(fsp
, conn
);
2823 file_sync_all(conn
);
2827 conn
->vfs_ops
.fsync(fsp
->fd
);
2830 DEBUG(3, ("flush\n"));
2835 /****************************************************************************
2837 ****************************************************************************/
2838 int reply_exit(connection_struct
* conn
,
2839 char *inbuf
, char *outbuf
, int dum_size
, int dum_buffsize
)
2841 int outsize
= set_message(outbuf
, 0, 0, True
);
2842 DEBUG(3, ("exit\n"));
2848 /****************************************************************************
2849 Reply to a close - has to deal with closing a directory opened by NT SMB's.
2850 ****************************************************************************/
2851 int reply_close(connection_struct
* conn
, char *inbuf
, char *outbuf
, int size
,
2856 int32 eclass
= 0, err
= 0;
2857 files_struct
*fsp
= NULL
;
2859 outsize
= set_message(outbuf
, 0, 0, True
);
2861 /* If it's an IPC, pass off to the pipe handler. */
2863 return reply_pipe_close(conn
, inbuf
, outbuf
);
2865 fsp
= file_fsp(inbuf
, smb_vwv0
);
2868 * We can only use CHECK_FSP if we know it's not a directory.
2871 if (!fsp
|| (fsp
->conn
!= conn
))
2872 return (ERROR(ERRDOS
, ERRbadfid
));
2874 if (HAS_CACHED_ERROR(fsp
))
2876 eclass
= fsp
->wbmpx_ptr
->wr_errclass
;
2877 err
= fsp
->wbmpx_ptr
->wr_error
;
2880 if (fsp
->is_directory
|| fsp
->stat_open
)
2883 * Special case - close NT SMB directory or stat file
2887 ("close %s fnum=%d\n",
2888 fsp
->is_directory
? "directory" : "stat file open",
2890 close_file(fsp
, True
);
2895 * Close ordinary file.
2900 * If there was a modify time outstanding,
2901 * try and set it here.
2903 if (fsp
->pending_modtime
)
2904 set_filetime(conn
, fsp
->fsp_name
,
2905 fsp
->pending_modtime
);
2908 * Now take care of any time sent in the close.
2910 mtime
= make_unix_date3(inbuf
+ smb_vwv1
);
2912 /* try and set the date */
2913 set_filetime(conn
, fsp
->fsp_name
, mtime
);
2915 DEBUG(3, ("close fd=%d fnum=%d (numopen=%d)\n",
2916 fsp
->fd
, fsp
->fnum
, conn
->num_files_open
));
2919 * close_file() returns the unix errno if an error
2920 * was detected on close - normally this is due to
2921 * a disk full error. If not then it was probably an I/O error.
2924 if ((close_err
= close_file(fsp
, True
)) != 0)
2927 return (UNIXERROR(ERRHRD
, ERRgeneral
));
2931 /* We have a cached error */
2933 return (ERROR(eclass
, err
));
2939 /****************************************************************************
2940 reply to a writeclose (Core+ protocol)
2941 ****************************************************************************/
2943 int reply_writeclose(connection_struct
* conn
,
2944 char *inbuf
, char *outbuf
, int size
, int dum_buffsize
)
2947 ssize_t nwritten
= -1;
2953 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
2955 CHECK_FSP(fsp
, conn
);
2959 numtowrite
= SVAL(inbuf
, smb_vwv1
);
2960 startpos
= IVAL(inbuf
, smb_vwv2
);
2961 mtime
= make_unix_date3(inbuf
+ smb_vwv4
);
2962 data
= smb_buf(inbuf
) + 1;
2965 (fsp
, conn
, (SMB_BIG_UINT
) numtowrite
, (SMB_BIG_UINT
) startpos
,
2967 return (ERROR(ERRDOS
, ERRlock
));
2969 nwritten
= write_file(fsp
, data
, startpos
, numtowrite
);
2971 set_filetime(conn
, fsp
->fsp_name
, mtime
);
2973 close_err
= close_file(fsp
, True
);
2975 DEBUG(3, ("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
2976 fsp
->fnum
, (int)numtowrite
, (int)nwritten
,
2977 conn
->num_files_open
));
2980 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
2985 return (UNIXERROR(ERRHRD
, ERRgeneral
));
2988 outsize
= set_message(outbuf
, 1, 0, True
);
2990 SSVAL(outbuf
, smb_vwv0
, nwritten
);
2995 /****************************************************************************
2997 ****************************************************************************/
2998 int reply_lock(connection_struct
* conn
,
2999 char *inbuf
, char *outbuf
, int length
, int dum_buffsize
)
3001 int outsize
= set_message(outbuf
, 0, 0, True
);
3002 SMB_BIG_UINT count
, offset
;
3005 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
3007 CHECK_FSP(fsp
, conn
);
3010 count
= (SMB_BIG_UINT
) IVAL(inbuf
, smb_vwv1
);
3011 offset
= (SMB_BIG_UINT
) IVAL(inbuf
, smb_vwv3
);
3013 DEBUG(3, ("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
3014 fsp
->fd
, fsp
->fnum
, (double)offset
, (double)count
));
3016 if (!do_lock(fsp
, conn
, count
, offset
, WRITE_LOCK
, &eclass
, &ecode
))
3018 if ((ecode
== ERRlock
) && lp_blocking_locks(SNUM(conn
)))
3021 * A blocking lock was requested. Package up
3022 * this smb into a queued request and push it
3023 * onto the blocking lock queue.
3025 if (push_blocking_lock_request(inbuf
, length
, -1, 0))
3028 return (ERROR(eclass
, ecode
));
3035 /****************************************************************************
3037 ****************************************************************************/
3038 int reply_unlock(connection_struct
* conn
, char *inbuf
, char *outbuf
,
3039 int size
, int dum_buffsize
)
3041 int outsize
= set_message(outbuf
, 0, 0, True
);
3042 SMB_BIG_UINT count
, offset
;
3045 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
3047 CHECK_FSP(fsp
, conn
);
3050 count
= (SMB_BIG_UINT
) IVAL(inbuf
, smb_vwv1
);
3051 offset
= (SMB_BIG_UINT
) IVAL(inbuf
, smb_vwv3
);
3053 if (!do_unlock(fsp
, conn
, count
, offset
, &eclass
, &ecode
))
3054 return (ERROR(eclass
, ecode
));
3056 DEBUG(3, ("unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
3057 fsp
->fd
, fsp
->fnum
, (double)offset
, (double)count
));
3063 /****************************************************************************
3065 ****************************************************************************/
3066 int reply_tdis(connection_struct
* conn
,
3067 char *inbuf
, char *outbuf
, int dum_size
, int dum_buffsize
)
3069 int outsize
= set_message(outbuf
, 0, 0, True
);
3072 vuid
= SVAL(inbuf
, smb_uid
);
3076 DEBUG(4, ("Invalid connection in tdis\n"));
3077 return (ERROR(ERRSRV
, ERRinvnid
));
3082 close_cnum(conn
, vuid
);
3089 /****************************************************************************
3091 ****************************************************************************/
3092 int reply_echo(connection_struct
* conn
,
3093 char *inbuf
, char *outbuf
, int dum_size
, int dum_buffsize
)
3095 int smb_reverb
= SVAL(inbuf
, smb_vwv0
);
3097 unsigned int data_len
= smb_buflen(inbuf
);
3098 int outsize
= set_message(outbuf
, 1, data_len
, True
);
3100 data_len
= MIN(data_len
, (sizeof(inbuf
)-(smb_buf(inbuf
)-inbuf
)));
3102 /* copy any incoming data back out */
3104 memcpy(smb_buf(outbuf
), smb_buf(inbuf
), data_len
);
3106 if (smb_reverb
> 100)
3109 ("large reverb (%d)?? Setting to 100\n", smb_reverb
));
3113 for (seq_num
= 1; seq_num
<= smb_reverb
; seq_num
++)
3115 SSVAL(outbuf
, smb_vwv0
, seq_num
);
3117 smb_setlen(outbuf
, outsize
- 4);
3119 send_smb(smbd_server_fd(), outbuf
);
3122 DEBUG(3, ("echo %d times\n", smb_reverb
));
3130 /****************************************************************************
3131 reply to a printopen
3132 ****************************************************************************/
3133 int reply_printopen(connection_struct
* conn
,
3134 char *inbuf
, char *outbuf
, int dum_size
, int dum_buffsize
)
3139 if (!CAN_PRINT(conn
))
3140 return (ERROR(ERRDOS
, ERRnoaccess
));
3142 /* Open for exclusive use, write only. */
3143 fsp
= print_fsp_open(conn
, "dos.prn");
3147 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
3150 outsize
= set_message(outbuf
, 1, 0, True
);
3151 SSVAL(outbuf
, smb_vwv0
, fsp
->fnum
);
3153 DEBUG(3, ("openprint fd=%d fnum=%d\n", fsp
->fd
, fsp
->fnum
));
3159 /****************************************************************************
3160 reply to a printclose
3161 ****************************************************************************/
3162 int reply_printclose(connection_struct
* conn
,
3163 char *inbuf
, char *outbuf
, int dum_size
,
3166 int outsize
= set_message(outbuf
, 0, 0, True
);
3167 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
3170 CHECK_FSP(fsp
, conn
);
3173 if (!CAN_PRINT(conn
))
3174 return (ERROR(ERRDOS
, ERRnoaccess
));
3176 DEBUG(3, ("printclose fd=%d fnum=%d\n", fsp
->fd
, fsp
->fnum
));
3178 close_err
= close_file(fsp
, True
);
3183 return (UNIXERROR(ERRHRD
, ERRgeneral
));
3190 /****************************************************************************
3191 reply to a printqueue
3192 ****************************************************************************/
3193 int reply_printqueue(connection_struct
* conn
,
3194 char *inbuf
, char *outbuf
, int dum_size
,
3197 int outsize
= set_message(outbuf
, 2, 3, True
);
3198 int max_count
= SVAL(inbuf
, smb_vwv0
);
3199 int start_index
= SVAL(inbuf
, smb_vwv1
);
3201 /* we used to allow the client to get the cnum wrong, but that
3202 is really quite gross and only worked when there was only
3203 one printer - I think we should now only accept it if they
3204 get it right (tridge) */
3205 if (!CAN_PRINT(conn
))
3206 return (ERROR(ERRDOS
, ERRnoaccess
));
3208 SSVAL(outbuf
, smb_vwv0
, 0);
3209 SSVAL(outbuf
, smb_vwv1
, 0);
3210 CVAL(smb_buf(outbuf
), 0) = 1;
3211 SSVAL(smb_buf(outbuf
), 1, 0);
3213 DEBUG(3, ("printqueue start_index=%d max_count=%d\n",
3214 start_index
, max_count
));
3217 print_queue_struct
*queue
= NULL
;
3218 char *p
= smb_buf(outbuf
) + 3;
3219 int count
= print_queue_status(SNUM(conn
), &queue
, NULL
);
3220 int num_to_get
= ABS(max_count
);
3223 0 ? start_index
: start_index
+ max_count
+ 1);
3229 num_to_get
= MIN(num_to_get
, count
- first
);
3232 for (i
= first
; i
< first
+ num_to_get
; i
++)
3234 put_dos_date2(p
, 0, queue
[i
].time
);
3236 (queue
[i
].status
== LPQ_PRINTING
? 2 : 3);
3237 SSVAL(p
, 5, queue
[i
].job
);
3238 SIVAL(p
, 7, queue
[i
].size
);
3240 StrnCpy(p
+ 12, queue
[i
].user
, 16);
3247 set_message(outbuf
, 2, 28 * count
+ 3, False
);
3248 SSVAL(outbuf
, smb_vwv0
, count
);
3249 SSVAL(outbuf
, smb_vwv1
,
3250 (max_count
> 0 ? first
+ count
: first
- 1));
3251 CVAL(smb_buf(outbuf
), 0) = 1;
3252 SSVAL(smb_buf(outbuf
), 1, 28 * count
);
3258 DEBUG(3, ("%d entries returned in queue\n", count
));
3265 /****************************************************************************
3266 reply to a printwrite
3267 ****************************************************************************/
3268 int reply_printwrite(connection_struct
* conn
, char *inbuf
, char *outbuf
,
3269 int dum_size
, int dum_buffsize
)
3272 int outsize
= set_message(outbuf
, 0, 0, True
);
3274 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
3276 if (!CAN_PRINT(conn
))
3277 return (ERROR(ERRDOS
, ERRnoaccess
));
3279 CHECK_FSP(fsp
, conn
);
3283 numtowrite
= SVAL(smb_buf(inbuf
), 1);
3284 data
= smb_buf(inbuf
) + 3;
3286 if (write_file(fsp
, data
, -1, numtowrite
) != numtowrite
)
3287 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
3289 DEBUG(3, ("printwrite fnum=%d num=%d\n", fsp
->fnum
, numtowrite
));
3295 /****************************************************************************
3297 ****************************************************************************/
3298 int reply_mkdir(connection_struct
* conn
, char *inbuf
, char *outbuf
,
3299 int dum_size
, int dum_buffsize
)
3302 int outsize
, ret
= -1;
3303 BOOL bad_path
= False
;
3305 pstrcpy(directory
, smb_buf(inbuf
) + 1);
3306 unix_convert(directory
, conn
, 0, &bad_path
, NULL
);
3308 if (check_name(directory
, conn
))
3309 ret
= conn
->vfs_ops
.mkdir(dos_to_unix(directory
, False
),
3310 unix_mode(conn
, aDIR
, directory
));
3314 if ((errno
== ENOENT
) && bad_path
)
3316 unix_ERR_class
= ERRDOS
;
3317 unix_ERR_code
= ERRbadpath
;
3319 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
3322 outsize
= set_message(outbuf
, 0, 0, True
);
3324 DEBUG(3, ("mkdir %s ret=%d\n", directory
, ret
));
3329 /****************************************************************************
3330 Static function used by reply_rmdir to delete an entire directory
3332 ****************************************************************************/
3333 static BOOL
recursive_rmdir(connection_struct
* conn
, char *directory
)
3337 void *dirptr
= OpenDir(NULL
, directory
, False
);
3342 while ((dname
= ReadDirName(dirptr
)))
3347 if ((strcmp(dname
, ".") == 0) || (strcmp(dname
, "..") == 0))
3350 /* Construct the full name. */
3351 if (strlen(directory
) + strlen(dname
) + 1 >= sizeof(fullname
))
3357 pstrcpy(fullname
, directory
);
3358 pstrcat(fullname
, "/");
3359 pstrcat(fullname
, dname
);
3361 if (conn
->vfs_ops
.lstat(dos_to_unix(fullname
, False
), &st
) !=
3368 if (st
.st_mode
& S_IFDIR
)
3370 if (recursive_rmdir(conn
, fullname
) != 0)
3376 rmdir(dos_to_unix(fullname
, False
)) != 0)
3382 else if (conn
->vfs_ops
.unlink(dos_to_unix(fullname
, False
)) !=
3393 /****************************************************************************
3394 The internals of the rmdir code - called elsewhere.
3395 ****************************************************************************/
3397 BOOL
rmdir_internals(connection_struct
* conn
, char *directory
)
3401 ok
= (conn
->vfs_ops
.rmdir(dos_to_unix(directory
, False
)) == 0);
3402 if (!ok
&& ((errno
== ENOTEMPTY
) || (errno
== EEXIST
))
3403 && lp_veto_files(SNUM(conn
)))
3406 * Check to see if the only thing in this directory are
3407 * vetoed files/directories. If so then delete them and
3408 * retry. If we fail to delete any of them (and we *don't*
3409 * do a recursive delete) then fail the rmdir.
3411 BOOL all_veto_files
= True
;
3413 void *dirptr
= OpenDir(conn
, directory
, False
);
3417 int dirpos
= TellDir(dirptr
);
3418 while ((dname
= ReadDirName(dirptr
)))
3420 if ((strcmp(dname
, ".") == 0)
3421 || (strcmp(dname
, "..") == 0))
3423 if (!IS_VETO_PATH(conn
, dname
))
3425 all_veto_files
= False
;
3431 SeekDir(dirptr
, dirpos
);
3432 while ((dname
= ReadDirName(dirptr
)))
3437 if ((strcmp(dname
, ".") == 0)
3438 || (strcmp(dname
, "..") == 0))
3441 /* Construct the full name. */
3442 if (strlen(directory
) +
3443 strlen(dname
) + 1 >=
3449 pstrcpy(fullname
, directory
);
3450 pstrcat(fullname
, "/");
3451 pstrcat(fullname
, dname
);
3458 if (st
.st_mode
& S_IFDIR
)
3460 if (lp_recursive_veto_delete
3474 else if (conn
->vfs_ops
.
3481 /* Retry the rmdir */
3484 rmdir(dos_to_unix(directory
, False
)) ==
3496 ("rmdir_internals: couldn't remove directory %s : %s\n",
3497 directory
, strerror(errno
)));
3502 /****************************************************************************
3504 ****************************************************************************/
3506 int reply_rmdir(connection_struct
* conn
, char *inbuf
, char *outbuf
,
3507 int dum_size
, int dum_buffsize
)
3512 BOOL bad_path
= False
;
3514 pstrcpy(directory
, smb_buf(inbuf
) + 1);
3516 RESOLVE_DFSPATH(directory
, conn
, inbuf
, outbuf
)
3517 unix_convert(directory
, conn
, NULL
, &bad_path
, NULL
);
3519 if (check_name(directory
, conn
))
3521 dptr_closepath(directory
, SVAL(inbuf
, smb_pid
));
3522 ok
= rmdir_internals(conn
, directory
);
3527 if ((errno
== ENOENT
) && bad_path
)
3529 unix_ERR_class
= ERRDOS
;
3530 unix_ERR_code
= ERRbadpath
;
3532 return (UNIXERROR(ERRDOS
, ERRbadpath
));
3535 outsize
= set_message(outbuf
, 0, 0, True
);
3537 DEBUG(3, ("rmdir %s\n", directory
));
3543 /*******************************************************************
3544 resolve wildcards in a filename rename
3545 ********************************************************************/
3546 static BOOL
resolve_wildcards(char *name1
, char *name2
)
3548 fstring root1
, root2
;
3552 name1
= strrchr(name1
, '/');
3553 name2
= strrchr(name2
, '/');
3555 if (!name1
|| !name2
)
3558 fstrcpy(root1
, name1
);
3559 fstrcpy(root2
, name2
);
3560 p
= strrchr(root1
, '.');
3564 fstrcpy(ext1
, p
+ 1);
3570 p
= strrchr(root2
, '.');
3574 fstrcpy(ext2
, p
+ 1);
3615 pstrcpy(name2
, root2
);
3618 pstrcat(name2
, ".");
3619 pstrcat(name2
, ext2
);
3625 /*******************************************************************
3626 check if a user is allowed to rename a file
3627 ********************************************************************/
3628 static BOOL
can_rename(char *fname
, connection_struct
* conn
)
3630 SMB_STRUCT_STAT sbuf
;
3632 if (!CAN_WRITE(conn
))
3635 if (conn
->vfs_ops
.lstat(dos_to_unix(fname
, False
), &sbuf
) != 0)
3637 if (!check_file_sharing(conn
, fname
, True
))
3643 /****************************************************************************
3644 The guts of the rename command, split out so it may be called by the NT SMB
3646 ****************************************************************************/
3647 int rename_internals(connection_struct
* conn
,
3648 char *inbuf
, char *outbuf
, char *name
,
3649 char *newname
, BOOL replace_if_exists
)
3653 pstring newname_last_component
;
3656 BOOL bad_path1
= False
;
3657 BOOL bad_path2
= False
;
3659 int error
= ERRnoaccess
;
3660 BOOL exists
= False
;
3664 *directory
= *mask
= 0;
3666 rc
= unix_convert(name
, conn
, 0, &bad_path1
, NULL
);
3667 unix_convert(newname
, conn
, newname_last_component
, &bad_path2
, NULL
);
3670 * Split the old name into directory and last component
3671 * strings. Note that unix_convert may have stripped off a
3672 * leading ./ from both name and newname if the rename is
3673 * at the root of the share. We need to make sure either both
3674 * name and newname contain a / character or neither of them do
3675 * as this is checked in resolve_wildcards().
3678 p
= strrchr(name
, '/');
3681 pstrcpy(directory
, ".");
3682 pstrcpy(mask
, name
);
3687 pstrcpy(directory
, name
);
3688 pstrcpy(mask
, p
+ 1);
3689 *p
= '/'; /* Replace needed for exceptional test below. */
3693 * We should only check the mangled cache
3694 * here if unix_convert failed. This means
3695 * that the path in 'mask' doesn't exist
3696 * on the file system and so we need to look
3697 * for a possible mangle. This patch from
3698 * Tine Smukavec <valentin.smukavec@hermes.si>.
3701 if (!rc
&& is_mangled(mask
))
3702 check_mangled_cache(mask
);
3704 has_wild
= strchr(mask
, '*') || strchr(mask
, '?');
3709 * No wildcards - just process the one file.
3711 BOOL is_short_name
= is_8_3(name
, True
);
3713 /* Add a terminating '/' to the directory name. */
3714 pstrcat(directory
, "/");
3715 pstrcat(directory
, mask
);
3717 /* Ensure newname contains a '/' also */
3718 if (strrchr(newname
, '/') == 0)
3722 pstrcpy(tmpstr
, "./");
3723 pstrcat(tmpstr
, newname
);
3724 pstrcpy(newname
, tmpstr
);
3728 ("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
3729 case_sensitive
, case_preserve
, short_case_preserve
,
3730 directory
, newname
, newname_last_component
,
3734 * Check for special case with case preserving and not
3735 * case sensitive, if directory and newname are identical,
3736 * and the old last component differs from the original
3737 * last component only by case, then we should allow
3738 * the rename (user is trying to change the case of the
3741 if ((case_sensitive
== False
) &&
3742 (((case_preserve
== True
) &&
3743 (is_short_name
== False
)) ||
3744 ((short_case_preserve
== True
) &&
3745 (is_short_name
== True
))) &&
3746 strcsequal(directory
, newname
))
3748 pstring newname_modified_last_component
;
3751 * Get the last component of the modified name.
3752 * Note that we guarantee that newname contains a '/'
3755 p
= strrchr(newname
, '/');
3756 pstrcpy(newname_modified_last_component
, p
+ 1);
3758 if (strcsequal(newname_modified_last_component
,
3759 newname_last_component
) == False
)
3762 * Replace the modified last component with
3765 pstrcpy(p
+ 1, newname_last_component
);
3769 pstrcpy(zdirectory
, dos_to_unix(directory
, False
));
3770 if (replace_if_exists
)
3773 * NT SMB specific flag - rename can overwrite
3774 * file with the same name so don't check for
3777 if (resolve_wildcards(directory
, newname
) &&
3778 can_rename(directory
, conn
) &&
3779 !conn
->vfs_ops
.rename(zdirectory
,
3780 dos_to_unix(newname
,
3786 if (resolve_wildcards(directory
, newname
) &&
3787 can_rename(directory
, conn
) &&
3788 !vfs_file_exist(conn
, newname
, NULL
) &&
3789 !conn
->vfs_ops
.rename(zdirectory
,
3790 dos_to_unix(newname
,
3796 ("rename_internals: %s doing rename on %s -> %s\n",
3797 (count
!= 0) ? "succeeded" : "failed", directory
,
3801 exists
= vfs_file_exist(conn
, directory
, NULL
);
3802 if (!count
&& exists
&& vfs_file_exist(conn
, newname
, NULL
))
3811 * Wildcards - process each file that matches.
3813 void *dirptr
= NULL
;
3817 if (check_name(directory
, conn
))
3818 dirptr
= OpenDir(conn
, directory
, True
);
3824 if (strequal(mask
, "????????.???"))
3827 while ((dname
= ReadDirName(dirptr
)))
3831 pstrcpy(fname
, dname
);
3834 (fname
, mask
, case_sensitive
, False
))
3837 error
= ERRnoaccess
;
3838 slprintf(fname
, sizeof(fname
) - 1, "%s/%s",
3840 if (!can_rename(fname
, conn
))
3843 ("rename %s refused\n", fname
));
3846 pstrcpy(destname
, newname
);
3848 if (!resolve_wildcards(fname
, destname
))
3851 ("resolve_wildcards %s %s failed\n",
3856 if (!replace_if_exists
&&
3857 vfs_file_exist(conn
, destname
, NULL
))
3860 ("file_exist %s\n", destname
));
3866 rename(dos_to_unix(fname
, False
),
3867 dos_to_unix(destname
, False
)))
3870 ("rename_internals: doing rename on %s -> %s\n",
3880 return (ERROR(ERRDOS
, error
));
3883 if ((errno
== ENOENT
) && (bad_path1
|| bad_path2
))
3885 unix_ERR_class
= ERRDOS
;
3886 unix_ERR_code
= ERRbadpath
;
3888 return (UNIXERROR(ERRDOS
, error
));
3895 /****************************************************************************
3897 ****************************************************************************/
3899 int reply_mv(connection_struct
* conn
, char *inbuf
, char *outbuf
,
3900 int dum_size
, int dum_buffsize
)
3906 pstrcpy(name
, smb_buf(inbuf
) + 1);
3907 pstrcpy(newname
, smb_buf(inbuf
) + 3 + strlen(name
));
3909 RESOLVE_DFSPATH(name
, conn
, inbuf
, outbuf
);
3910 RESOLVE_DFSPATH(newname
, conn
, inbuf
, outbuf
);
3912 DEBUG(3, ("reply_mv : %s -> %s\n", name
, newname
));
3914 outsize
= rename_internals(conn
, inbuf
, outbuf
, name
, newname
, False
);
3916 outsize
= set_message(outbuf
, 0, 0, True
);
3921 /*******************************************************************
3922 copy a file as part of a reply_copy
3923 ******************************************************************/
3925 static BOOL
copy_file(char *src
, char *dest1
, connection_struct
* conn
,
3926 int ofun
, int count
, BOOL target_is_directory
,
3932 files_struct
*fsp1
, *fsp2
;
3937 pstrcpy(dest
, dest1
);
3938 if (target_is_directory
)
3940 char *p
= strrchr(src
, '/');
3949 if (!vfs_file_exist(conn
, src
, &st
))
3953 open_file_shared(conn
, src
,
3954 SET_DENY_MODE(DENY_NONE
) |
3955 SET_OPEN_MODE(DOS_OPEN_RDONLY
),
3956 (FILE_FAIL_IF_NOT_EXIST
| FILE_EXISTS_OPEN
),
3957 0, 0, &Access
, &action
);
3964 if (!target_is_directory
&& count
)
3968 open_file_shared(conn
, dest
,
3969 SET_DENY_MODE(DENY_NONE
) |
3970 SET_OPEN_MODE(DOS_OPEN_WRONLY
), ofun
,
3971 st
.st_mode
, 0, &Access
, &action
);
3975 close_file(fsp1
, False
);
3979 if ((ofun
& 3) == 1)
3981 if (conn
->vfs_ops
.lseek(fsp2
->fd
, 0, SEEK_END
) == -1)
3984 ("copy_file: error - sys_lseek returned error %s\n",
3987 * Stop the copy from occurring.
3996 vfs_transfer_file(-1, fsp1
, -1, fsp2
, st
.st_size
,
3999 close_file(fsp1
, False
);
4001 * As we are opening fsp1 read-only we only expect
4002 * an error on close on fsp2 if we are out of space.
4003 * Thus we don't look at the error return from the
4006 *err_ret
= close_file(fsp2
, False
);
4008 return (ret
== (SMB_OFF_T
) st
.st_size
);
4013 /****************************************************************************
4014 reply to a file copy.
4015 ****************************************************************************/
4016 int reply_copy(connection_struct
* conn
, char *inbuf
, char *outbuf
,
4017 int dum_size
, int dum_buffsize
)
4022 pstring mask
, newname
;
4025 int error
= ERRnoaccess
;
4028 BOOL exists
= False
;
4029 int tid2
= SVAL(inbuf
, smb_vwv0
);
4030 int ofun
= SVAL(inbuf
, smb_vwv1
);
4031 int flags
= SVAL(inbuf
, smb_vwv2
);
4032 BOOL target_is_directory
= False
;
4033 BOOL bad_path1
= False
;
4034 BOOL bad_path2
= False
;
4037 *directory
= *mask
= 0;
4039 pstrcpy(name
, smb_buf(inbuf
));
4040 pstrcpy(newname
, smb_buf(inbuf
) + 1 + strlen(name
));
4042 DEBUG(3, ("reply_copy : %s -> %s\n", name
, newname
));
4044 if (tid2
!= conn
->cnum
)
4046 /* can't currently handle inter share copies XXXX */
4047 DEBUG(3, ("Rejecting inter-share copy\n"));
4048 return (ERROR(ERRSRV
, ERRinvdevice
));
4051 RESOLVE_DFSPATH(name
, conn
, inbuf
, outbuf
);
4052 RESOLVE_DFSPATH(newname
, conn
, inbuf
, outbuf
);
4054 rc
= unix_convert(name
, conn
, 0, &bad_path1
, NULL
);
4055 unix_convert(newname
, conn
, 0, &bad_path2
, NULL
);
4057 target_is_directory
= vfs_directory_exist(conn
, False
, NULL
);
4059 if ((flags
& 1) && target_is_directory
)
4061 return (ERROR(ERRDOS
, ERRbadfile
));
4064 if ((flags
& 2) && !target_is_directory
)
4066 return (ERROR(ERRDOS
, ERRbadpath
));
4069 if ((flags
& (1 << 5)) && vfs_directory_exist(conn
, name
, NULL
))
4071 /* wants a tree copy! XXXX */
4072 DEBUG(3, ("Rejecting tree copy\n"));
4073 return (ERROR(ERRSRV
, ERRerror
));
4076 p
= strrchr(name
, '/');
4079 pstrcpy(directory
, "./");
4080 pstrcpy(mask
, name
);
4085 pstrcpy(directory
, name
);
4086 pstrcpy(mask
, p
+ 1);
4090 * We should only check the mangled cache
4091 * here if unix_convert failed. This means
4092 * that the path in 'mask' doesn't exist
4093 * on the file system and so we need to look
4094 * for a possible mangle. This patch from
4095 * Tine Smukavec <valentin.smukavec@hermes.si>.
4098 if (!rc
&& is_mangled(mask
))
4099 check_mangled_cache(mask
);
4101 has_wild
= strchr(mask
, '*') || strchr(mask
, '?');
4105 pstrcat(directory
, "/");
4106 pstrcat(directory
, mask
);
4107 if (resolve_wildcards(directory
, newname
) &&
4108 copy_file(directory
, newname
, conn
, ofun
,
4109 count
, target_is_directory
, &err
))
4114 return (UNIXERROR(ERRHRD
, ERRgeneral
));
4117 exists
= vfs_file_exist(conn
, directory
, NULL
);
4121 void *dirptr
= NULL
;
4125 if (check_name(directory
, conn
))
4126 dirptr
= OpenDir(conn
, directory
, True
);
4132 if (strequal(mask
, "????????.???"))
4135 while ((dname
= ReadDirName(dirptr
)))
4138 pstrcpy(fname
, dname
);
4141 (fname
, mask
, case_sensitive
, False
))
4144 error
= ERRnoaccess
;
4145 slprintf(fname
, sizeof(fname
) - 1, "%s/%s",
4147 pstrcpy(destname
, newname
);
4148 if (resolve_wildcards(fname
, destname
) &&
4149 copy_file(fname
, destname
, conn
, ofun
,
4150 count
, target_is_directory
,
4153 ("reply_copy : doing copy on %s -> %s\n",
4164 /* Error on close... */
4166 return (UNIXERROR(ERRHRD
, ERRgeneral
));
4170 return (ERROR(ERRDOS
, error
));
4173 if ((errno
== ENOENT
) && (bad_path1
|| bad_path2
))
4175 unix_ERR_class
= ERRDOS
;
4176 unix_ERR_code
= ERRbadpath
;
4178 return (UNIXERROR(ERRDOS
, error
));
4182 outsize
= set_message(outbuf
, 1, 0, True
);
4183 SSVAL(outbuf
, smb_vwv0
, count
);
4188 /****************************************************************************
4190 ****************************************************************************/
4191 int reply_setdir(connection_struct
* conn
, char *inbuf
, char *outbuf
,
4192 int dum_size
, int dum_buffsize
)
4200 if (!CAN_SETDIR(snum
))
4201 return (ERROR(ERRDOS
, ERRnoaccess
));
4203 pstrcpy(newdir
, smb_buf(inbuf
) + 1);
4206 if (strlen(newdir
) == 0)
4212 ok
= vfs_directory_exist(conn
, newdir
, NULL
);
4215 string_set(&conn
->connectpath
, newdir
);
4220 return (ERROR(ERRDOS
, ERRbadpath
));
4222 outsize
= set_message(outbuf
, 0, 0, True
);
4223 CVAL(outbuf
, smb_reh
) = CVAL(inbuf
, smb_reh
);
4225 DEBUG(3, ("setdir %s\n", newdir
));
4230 /****************************************************************************
4231 reply to a lockingX request
4232 ****************************************************************************/
4234 int reply_lockingX(connection_struct
* conn
, char *inbuf
, char *outbuf
,
4235 int length
, int bufsize
)
4237 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv2
);
4238 unsigned char locktype
= CVAL(inbuf
, smb_vwv3
);
4240 unsigned char oplocklevel
= CVAL(inbuf
, smb_vwv3
+ 1);
4242 uint16 num_ulocks
= SVAL(inbuf
, smb_vwv6
);
4243 uint16 num_locks
= SVAL(inbuf
, smb_vwv7
);
4244 SMB_BIG_UINT count
= 0, offset
= 0;
4245 int32 lock_timeout
= IVAL(inbuf
, smb_vwv4
);
4248 uint32 ecode
= 0, dummy2
;
4249 int eclass
= 0, dummy1
;
4250 BOOL large_file_format
= (locktype
& LOCKING_ANDX_LARGE_FILES
);
4253 CHECK_FSP(fsp
, conn
);
4256 data
= smb_buf(inbuf
);
4258 /* Check if this is an oplock break on a file
4259 we have granted an oplock on.
4261 if ((locktype
& LOCKING_ANDX_OPLOCK_RELEASE
))
4264 ("reply_lockingX: oplock break reply from client for fnum = %d\n",
4268 * Make sure we have granted an exclusive or batch oplock on this file.
4271 if (!EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
))
4274 ("reply_lockingX: Error : oplock break from client for fnum = %d and \
4275 no oplock granted on this file (%s).\n",
4276 fsp
->fnum
, fsp
->fsp_name
));
4278 /* if this is a pure oplock break request then don't send a reply */
4279 if (num_locks
== 0 && num_ulocks
== 0)
4282 return ERROR(ERRDOS
, ERRlock
);
4285 if (remove_oplock(fsp
) == False
)
4288 ("reply_lockingX: error in removing oplock on file %s\n",
4292 /* if this is a pure oplock break request then don't send a reply */
4293 if (num_locks
== 0 && num_ulocks
== 0)
4295 /* Sanity check - ensure a pure oplock break is not a
4297 if (CVAL(inbuf
, smb_vwv0
) != 0xff)
4299 ("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
4300 (unsigned int)CVAL(inbuf
, smb_vwv0
)));
4305 /* Data now points at the beginning of the list
4306 of smb_unlkrng structs */
4307 for (i
= 0; i
< (int)num_ulocks
; i
++)
4309 count
= get_lock_count(data
, i
, large_file_format
);
4310 offset
= get_lock_offset(data
, i
, large_file_format
, &err
);
4313 * There is no error code marked "stupid client bug".... :-).
4316 return ERROR(ERRDOS
, ERRnoaccess
);
4319 ("reply_lockingX: unlock start=%.0f, len=%.0f for file %s\n",
4320 (double)offset
, (double)count
, fsp
->fsp_name
));
4322 if (!do_unlock(fsp
, conn
, count
, offset
, &eclass
, &ecode
))
4323 return ERROR(eclass
, ecode
);
4326 /* Setup the timeout in seconds. */
4327 lock_timeout
= ((lock_timeout
== -1) ? -1 : lock_timeout
/ 1000);
4329 /* Now do any requested locks */
4330 data
+= ((large_file_format
? 20 : 10) * num_ulocks
);
4332 /* Data now points at the beginning of the list
4333 of smb_lkrng structs */
4335 for (i
= 0; i
< (int)num_locks
; i
++)
4337 count
= get_lock_count(data
, i
, large_file_format
);
4338 offset
= get_lock_offset(data
, i
, large_file_format
, &err
);
4341 * There is no error code marked "stupid client bug".... :-).
4344 return ERROR(ERRDOS
, ERRnoaccess
);
4347 ("reply_lockingX: lock start=%.0f, len=%.0f for file %s\n",
4348 (double)offset
, (double)count
, fsp
->fsp_name
));
4351 (fsp
, conn
, count
, offset
,
4352 ((locktype
& 1) ? READ_LOCK
: WRITE_LOCK
), &eclass
,
4355 if ((ecode
== ERRlock
) && (lock_timeout
!= 0)
4356 && lp_blocking_locks(SNUM(conn
)))
4359 * A blocking lock was requested. Package up
4360 * this smb into a queued request and push it
4361 * onto the blocking lock queue.
4363 if (push_blocking_lock_request
4364 (inbuf
, length
, lock_timeout
, i
))
4371 /* If any of the above locks failed, then we must unlock
4372 all of the previous locks (X/Open spec). */
4373 if (i
!= num_locks
&& num_locks
!= 0)
4376 * Ensure we don't do a remove on the lock that just failed,
4377 * as under POSIX rules, if we have a lock already there, we
4378 * will delete it (and we shouldn't) .....
4380 for (i
--; i
>= 0; i
--)
4382 count
= get_lock_count(data
, i
, large_file_format
);
4384 get_lock_offset(data
, i
, large_file_format
,
4388 * There is no error code marked "stupid client bug".... :-).
4391 return ERROR(ERRDOS
, ERRnoaccess
);
4393 do_unlock(fsp
, conn
, count
, offset
, &dummy1
, &dummy2
);
4395 return ERROR(eclass
, ecode
);
4398 set_message(outbuf
, 2, 0, True
);
4400 DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
4401 fsp
->fnum
, (unsigned int)locktype
, num_locks
, num_ulocks
));
4403 return chain_reply(inbuf
, outbuf
, length
, bufsize
);
4407 /****************************************************************************
4408 reply to a SMBreadbmpx (read block multiplex) request
4409 ****************************************************************************/
4410 int reply_readbmpx(connection_struct
* conn
, char *inbuf
, char *outbuf
,
4411 int length
, int bufsize
)
4422 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
4424 /* this function doesn't seem to work - disable by default */
4426 return (ERROR(ERRSRV
, ERRuseSTD
));
4428 outsize
= set_message(outbuf
, 8, 0, True
);
4430 CHECK_FSP(fsp
, conn
);
4434 startpos
= IVAL(inbuf
, smb_vwv1
);
4435 maxcount
= SVAL(inbuf
, smb_vwv3
);
4437 data
= smb_buf(outbuf
);
4438 pad
= ((long)data
) % 4;
4443 max_per_packet
= bufsize
- (outsize
+ pad
);
4448 (fsp
, conn
, (SMB_BIG_UINT
) maxcount
, (SMB_BIG_UINT
) startpos
,
4450 return (ERROR(ERRDOS
, ERRlock
));
4454 size_t N
= MIN(max_per_packet
, tcount
- total_read
);
4456 nread
= read_file(fsp
, data
, startpos
, N
);
4461 if (nread
< (ssize_t
) N
)
4462 tcount
= total_read
+ nread
;
4464 set_message(outbuf
, 8, nread
, False
);
4465 SIVAL(outbuf
, smb_vwv0
, startpos
);
4466 SSVAL(outbuf
, smb_vwv2
, tcount
);
4467 SSVAL(outbuf
, smb_vwv6
, nread
);
4468 SSVAL(outbuf
, smb_vwv7
, smb_offset(data
, outbuf
));
4470 send_smb(smbd_server_fd(), outbuf
);
4472 total_read
+= nread
;
4475 while (total_read
< (ssize_t
) tcount
);
4480 /****************************************************************************
4481 reply to a SMBwritebmpx (write block multiplex primary) request
4482 ****************************************************************************/
4484 int reply_writebmpx(connection_struct
* conn
, char *inbuf
, char *outbuf
,
4485 int size
, int dum_buffsize
)
4488 ssize_t nwritten
= -1;
4495 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
4497 CHECK_FSP(fsp
, conn
);
4501 tcount
= SVAL(inbuf
, smb_vwv1
);
4502 startpos
= IVAL(inbuf
, smb_vwv3
);
4503 write_through
= BITSETW(inbuf
+ smb_vwv7
, 0);
4504 numtowrite
= SVAL(inbuf
, smb_vwv10
);
4505 smb_doff
= SVAL(inbuf
, smb_vwv11
);
4507 data
= smb_base(inbuf
) + smb_doff
;
4509 /* If this fails we need to send an SMBwriteC response,
4510 not an SMBwritebmpx - set this up now so we don't forget */
4511 CVAL(outbuf
, smb_com
) = SMBwritec
;
4514 (fsp
, conn
, (SMB_BIG_UINT
) tcount
, (SMB_BIG_UINT
) startpos
,
4516 return (ERROR(ERRDOS
, ERRlock
));
4518 nwritten
= write_file(fsp
, data
, startpos
, numtowrite
);
4520 if (lp_syncalways(SNUM(conn
)) || write_through
)
4521 conn
->vfs_ops
.fsync(fsp
->fd
);
4523 if (nwritten
< (ssize_t
) numtowrite
)
4524 return (UNIXERROR(ERRHRD
, ERRdiskfull
));
4526 /* If the maximum to be written to this file
4527 is greater than what we just wrote then set
4528 up a secondary struct to be attached to this
4529 fd, we will use this to cache error messages etc. */
4530 if ((ssize_t
) tcount
> nwritten
)
4532 write_bmpx_struct
*wbms
;
4533 if (fsp
->wbmpx_ptr
!= NULL
)
4534 wbms
= fsp
->wbmpx_ptr
; /* Use an existing struct */
4537 (write_bmpx_struct
*)
4538 malloc(sizeof(write_bmpx_struct
));
4541 DEBUG(0, ("Out of memory in reply_readmpx\n"));
4542 return (ERROR(ERRSRV
, ERRnoresource
));
4544 wbms
->wr_mode
= write_through
;
4545 wbms
->wr_discard
= False
; /* No errors yet */
4546 wbms
->wr_total_written
= nwritten
;
4547 wbms
->wr_errclass
= 0;
4549 fsp
->wbmpx_ptr
= wbms
;
4552 /* We are returning successfully, set the message type back to
4554 CVAL(outbuf
, smb_com
) = SMBwriteBmpx
;
4556 outsize
= set_message(outbuf
, 1, 0, True
);
4558 SSVALS(outbuf
, smb_vwv0
, -1); /* We don't support smb_remaining */
4560 DEBUG(3, ("writebmpx fnum=%d num=%d wrote=%d\n",
4561 fsp
->fnum
, (int)numtowrite
, (int)nwritten
));
4563 if (write_through
&& tcount
== nwritten
)
4565 /* we need to send both a primary and a secondary response */
4566 smb_setlen(outbuf
, outsize
- 4);
4567 send_smb(smbd_server_fd(), outbuf
);
4569 /* now the secondary */
4570 outsize
= set_message(outbuf
, 1, 0, True
);
4571 CVAL(outbuf
, smb_com
) = SMBwritec
;
4572 SSVAL(outbuf
, smb_vwv0
, nwritten
);
4579 /****************************************************************************
4580 reply to a SMBwritebs (write block multiplex secondary) request
4581 ****************************************************************************/
4582 int reply_writebs(connection_struct
* conn
, char *inbuf
, char *outbuf
,
4583 int dum_size
, int dum_buffsize
)
4586 ssize_t nwritten
= -1;
4593 write_bmpx_struct
*wbms
;
4594 BOOL send_response
= False
;
4595 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
4597 CHECK_FSP(fsp
, conn
);
4600 tcount
= SVAL(inbuf
, smb_vwv1
);
4601 startpos
= IVAL(inbuf
, smb_vwv2
);
4602 numtowrite
= SVAL(inbuf
, smb_vwv6
);
4603 smb_doff
= SVAL(inbuf
, smb_vwv7
);
4605 data
= smb_base(inbuf
) + smb_doff
;
4607 /* We need to send an SMBwriteC response, not an SMBwritebs */
4608 CVAL(outbuf
, smb_com
) = SMBwritec
;
4610 /* This fd should have an auxiliary struct attached,
4611 check that it does */
4612 wbms
= fsp
->wbmpx_ptr
;
4616 /* If write through is set we can return errors, else we must
4618 write_through
= wbms
->wr_mode
;
4620 /* Check for an earlier error */
4621 if (wbms
->wr_discard
)
4622 return -1; /* Just discard the packet */
4624 nwritten
= write_file(fsp
, data
, startpos
, numtowrite
);
4626 if (lp_syncalways(SNUM(conn
)) || write_through
)
4627 conn
->vfs_ops
.fsync(fsp
->fd
);
4629 if (nwritten
< (ssize_t
) numtowrite
)
4633 /* We are returning an error - we can delete the aux struct */
4636 fsp
->wbmpx_ptr
= NULL
;
4637 return (ERROR(ERRHRD
, ERRdiskfull
));
4639 return (CACHE_ERROR(wbms
, ERRHRD
, ERRdiskfull
));
4642 /* Increment the total written, if this matches tcount
4643 we can discard the auxiliary struct (hurrah !) and return a writeC */
4644 wbms
->wr_total_written
+= nwritten
;
4645 if (wbms
->wr_total_written
>= tcount
)
4649 outsize
= set_message(outbuf
, 1, 0, True
);
4650 SSVAL(outbuf
, smb_vwv0
, wbms
->wr_total_written
);
4651 send_response
= True
;
4655 fsp
->wbmpx_ptr
= NULL
;
4665 /****************************************************************************
4666 reply to a SMBsetattrE
4667 ****************************************************************************/
4669 int reply_setattrE(connection_struct
* conn
, char *inbuf
, char *outbuf
,
4670 int size
, int dum_buffsize
)
4672 struct utimbuf unix_times
;
4674 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
4676 outsize
= set_message(outbuf
, 0, 0, True
);
4678 CHECK_FSP(fsp
, conn
);
4681 /* Convert the DOS times into unix times. Ignore create
4682 time as UNIX can't set this.
4684 unix_times
.actime
= make_unix_date2(inbuf
+ smb_vwv3
);
4685 unix_times
.modtime
= make_unix_date2(inbuf
+ smb_vwv5
);
4688 * Patch from Ray Frush <frush@engr.colostate.edu>
4689 * Sometimes times are sent as zero - ignore them.
4692 if ((unix_times
.actime
== 0) && (unix_times
.modtime
== 0))
4694 /* Ignore request */
4697 dbgtext("reply_setattrE fnum=%d ", fsp
->fnum
);
4699 ("ignoring zero request - not setting timestamps of 0\n");
4703 else if ((unix_times
.actime
!= 0) && (unix_times
.modtime
== 0))
4705 /* set modify time = to access time if modify time was 0 */
4706 unix_times
.modtime
= unix_times
.actime
;
4709 /* Set the date on this file */
4710 if (file_utime(conn
, fsp
->fsp_name
, &unix_times
))
4711 return (ERROR(ERRDOS
, ERRnoaccess
));
4713 DEBUG(3, ("reply_setattrE fnum=%d actime=%d modtime=%d\n",
4714 fsp
->fnum
, (int)unix_times
.actime
,
4715 (int)unix_times
.modtime
));
4721 /****************************************************************************
4722 reply to a SMBgetattrE
4723 ****************************************************************************/
4725 int reply_getattrE(connection_struct
* conn
, char *inbuf
, char *outbuf
,
4726 int size
, int dum_buffsize
)
4728 SMB_STRUCT_STAT sbuf
;
4731 files_struct
*fsp
= file_fsp(inbuf
, smb_vwv0
);
4733 outsize
= set_message(outbuf
, 11, 0, True
);
4735 CHECK_FSP(fsp
, conn
);
4738 /* Do an fstat on this file */
4739 if (fsp
->conn
->vfs_ops
.fstat(fsp
->fd
, &sbuf
))
4740 return (UNIXERROR(ERRDOS
, ERRnoaccess
));
4742 mode
= dos_mode(conn
, fsp
->fsp_name
, &sbuf
);
4744 /* Convert the times into dos times. Set create
4745 date to be last modify date as UNIX doesn't save
4747 put_dos_date2(outbuf
, smb_vwv0
,
4748 get_create_time(&sbuf
,
4749 lp_fake_dir_create_times(SNUM(conn
))));
4750 put_dos_date2(outbuf
, smb_vwv2
, sbuf
.st_atime
);
4751 put_dos_date2(outbuf
, smb_vwv4
, sbuf
.st_mtime
);
4754 SIVAL(outbuf
, smb_vwv6
, 0);
4755 SIVAL(outbuf
, smb_vwv8
, 0);
4759 SIVAL(outbuf
, smb_vwv6
, (uint32
)sbuf
.st_size
);
4760 SIVAL(outbuf
, smb_vwv8
, SMB_ROUNDUP(sbuf
.st_size
, 1024));
4762 SSVAL(outbuf
, smb_vwv10
, mode
);
4764 DEBUG(3, ("reply_getattrE fnum=%d\n", fsp
->fnum
));