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
31 /* look in server.c for some explanation of these variables */
33 extern int DEBUGLEVEL;
36 extern char magic_char;
37 extern BOOL case_sensitive;
38 extern BOOL case_preserve;
39 extern BOOL short_case_preserve;
40 extern pstring sesssetup_user;
41 extern pstring global_myname;
42 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)
55 dbgtext( "ERROR: Invalid password length %d.\n", len );
56 dbgtext( "Your machine may be under attack by someone " );
57 dbgtext( "attempting to exploit an old bug.\n" );
58 dbgtext( "Attack was from IP = %s.\n", client_addr(Client) );
60 exit_server("possible attack");
64 /****************************************************************************
65 reply to an special message
66 ****************************************************************************/
68 int reply_special(char *inbuf,char *outbuf)
71 int msg_type = CVAL(inbuf,0);
72 int msg_flags = CVAL(inbuf,1);
74 extern fstring remote_machine;
75 extern fstring local_machine;
81 memset(outbuf,'\0',smb_size);
86 case 0x81: /* session request */
87 CVAL(outbuf,0) = 0x82;
89 if (name_len(inbuf+4) > 50 ||
90 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
91 DEBUG(0,("Invalid name length in session request\n"));
94 name_extract(inbuf,4,name1);
95 name_extract(inbuf,4 + name_len(inbuf + 4),name2);
96 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
99 fstrcpy(remote_machine,name2);
100 remote_machine[15] = 0;
101 trim_string(remote_machine," "," ");
102 strlower(remote_machine);
104 fstrcpy(local_machine,name1);
105 len = strlen(local_machine);
107 name_type = local_machine[15];
108 local_machine[15] = 0;
110 trim_string(local_machine," "," ");
111 strlower(local_machine);
113 if (name_type == 'R') {
114 /* We are being asked for a pathworks session ---
116 CVAL(outbuf, 0) = 0x83;
120 add_session_user(remote_machine);
122 reload_services(True);
126 claim_connection(NULL,"STATUS.",MAXSTATUS,True);
131 case 0x89: /* session keepalive request
132 (some old clients produce this?) */
133 CVAL(outbuf,0) = 0x85;
137 case 0x82: /* positive session response */
138 case 0x83: /* negative session response */
139 case 0x84: /* retarget session response */
140 DEBUG(0,("Unexpected session response\n"));
143 case 0x85: /* session keepalive */
148 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
149 msg_type, msg_flags));
155 /*******************************************************************
156 work out what error to give to a failed connection
157 ********************************************************************/
159 static int connection_error(char *inbuf,char *outbuf,int ecode)
161 if (ecode == ERRnoipc)
162 return(ERROR(ERRDOS,ERRnoipc));
164 return(ERROR(ERRSRV,ecode));
169 /****************************************************************************
170 parse a share descriptor string
171 ****************************************************************************/
172 static void parse_connect(char *p,char *service,char *user,
173 char *password,int *pwlen,char *dev)
177 DEBUG(4,("parsing connect string %s\n",p));
179 p2 = strrchr(p,'\\');
183 fstrcpy(service,p2+1);
188 *pwlen = strlen(password);
195 p = strchr(service,'%');
203 /****************************************************************************
205 ****************************************************************************/
207 int reply_tcon(connection_struct *conn,
208 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
210 BOOL doencrypt = SMBENCRYPT();
216 uint16 vuid = SVAL(inbuf,smb_uid);
220 *service = *user = *password = *dev = 0;
222 parse_connect(smb_buf(inbuf)+1,service,user,password,&pwlen,dev);
225 * Ensure the user and password names are in UNIX codepage format.
228 dos_to_unix(user,True);
230 dos_to_unix(password,True);
233 * Pass the user through the NT -> unix user mapping
237 (void)map_username(user);
240 * Do any UNIX username case mangling.
242 (void)Get_Pwnam( user, True);
244 conn = make_connection(service,user,password,pwlen,dev,vuid,&ecode);
247 return(connection_error(inbuf,outbuf,ecode));
250 outsize = set_message(outbuf,2,0,True);
251 SSVAL(outbuf,smb_vwv0,max_recv);
252 SSVAL(outbuf,smb_vwv1,conn->cnum);
253 SSVAL(outbuf,smb_tid,conn->cnum);
255 DEBUG(3,("tcon service=%s user=%s cnum=%d\n",
256 service, user, conn->cnum));
261 /****************************************************************************
262 Reply to a tcon and X.
263 ****************************************************************************/
265 int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
271 BOOL doencrypt = SMBENCRYPT();
273 uint16 vuid = SVAL(inbuf,smb_uid);
274 int passlen = SVAL(inbuf,smb_vwv3);
278 *service = *user = *password = *devicename = 0;
280 /* we might have to close an old one */
281 if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
282 close_cnum(conn,vuid);
285 if (passlen > MAX_PASS_LEN) {
286 overflow_attack(passlen);
289 memcpy(password,smb_buf(inbuf),passlen);
291 path = smb_buf(inbuf) + passlen;
294 if (strequal(password," "))
296 passlen = strlen(password);
299 fstrcpy(service,path+2);
300 p = strchr(service,'\\');
302 return(ERROR(ERRSRV,ERRinvnetname));
304 fstrcpy(service,p+1);
305 p = strchr(service,'%');
310 StrnCpy(devicename,path + strlen(path) + 1,6);
311 DEBUG(4,("Got device type %s\n",devicename));
314 * Ensure the user and password names are in UNIX codepage format.
317 dos_to_unix(user,True);
319 dos_to_unix(password,True);
322 * Pass the user through the NT -> unix user mapping
326 (void)map_username(user);
329 * Do any UNIX username case mangling.
331 (void)Get_Pwnam(user, True);
333 conn = make_connection(service,user,password,passlen,devicename,vuid,&ecode);
336 return(connection_error(inbuf,outbuf,ecode));
338 if (Protocol < PROTOCOL_NT1) {
339 set_message(outbuf,2,strlen(devicename)+1,True);
340 pstrcpy(smb_buf(outbuf),devicename);
342 char *fsname = lp_fstype(SNUM(conn));
344 set_message(outbuf,3,3,True);
347 pstrcpy(p,devicename); p = skip_string(p,1); /* device name */
348 pstrcpy(p,fsname); p = skip_string(p,1); /* filesystem type e.g NTFS */
350 set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
352 /* what does setting this bit do? It is set by NT4 and
353 may affect the ability to autorun mounted cdroms */
354 SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS);
357 DEBUG(3,("tconX service=%s user=%s\n",
360 /* set the incoming and outgoing tid to the just created one */
361 SSVAL(inbuf,smb_tid,conn->cnum);
362 SSVAL(outbuf,smb_tid,conn->cnum);
364 return chain_reply(inbuf,outbuf,length,bufsize);
368 /****************************************************************************
369 reply to an unknown type
370 ****************************************************************************/
371 int reply_unknown(char *inbuf,char *outbuf)
374 type = CVAL(inbuf,smb_com);
376 DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
377 smb_fn_name(type), type, type));
379 return(ERROR(ERRSRV,ERRunknownsmb));
383 /****************************************************************************
385 ****************************************************************************/
386 int reply_ioctl(connection_struct *conn,
387 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
389 uint16 device = SVAL(inbuf,smb_vwv1);
390 uint16 function = SVAL(inbuf,smb_vwv2);
391 uint32 ioctl_code = (device << 16) + function;
392 int replysize, outsize;
395 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
399 case IOCTL_QUERY_JOB_INFO:
403 return(ERROR(ERRSRV,ERRnosupport));
406 outsize = set_message(outbuf,8,replysize+1,True);
407 SSVAL(outbuf,smb_vwv1,replysize); /* Total data bytes returned */
408 SSVAL(outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
409 SSVAL(outbuf,smb_vwv6,52); /* Offset to data */
410 p = smb_buf(outbuf) + 1; /* Allow for alignment */
414 case IOCTL_QUERY_JOB_INFO:
415 SSVAL(p,0,1); /* Job number */
416 StrnCpy(p+2, global_myname, 15); /* Our NetBIOS name */
417 StrnCpy(p+18, lp_servicename(SNUM(conn)), 13); /* Service name */
424 /****************************************************************************
425 always return an error: it's just a matter of which one...
426 ****************************************************************************/
427 static int session_trust_account(connection_struct *conn, char *inbuf, char *outbuf, char *user,
428 char *smb_passwd, int smb_passlen,
429 char *smb_nt_passwd, int smb_nt_passlen)
431 struct smb_passwd *smb_trust_acct = NULL; /* check if trust account exists */
432 if (lp_security() == SEC_USER)
434 smb_trust_acct = getsmbpwnam(user);
438 DEBUG(0,("session_trust_account: Trust account %s only supported with security = user\n", user));
439 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
440 return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
443 if (smb_trust_acct == NULL)
445 /* lkclXXXX: workstation entry doesn't exist */
446 DEBUG(0,("session_trust_account: Trust account %s user doesn't exist\n",user));
447 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
448 return(ERROR(0, 0xc0000000|NT_STATUS_NO_SUCH_USER));
452 if ((smb_passlen != 24) || (smb_nt_passlen != 24))
454 DEBUG(0,("session_trust_account: Trust account %s - password length wrong.\n", user));
455 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
456 return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
459 if (!smb_password_ok(smb_trust_acct, NULL, (unsigned char *)smb_passwd, (unsigned char *)smb_nt_passwd))
461 DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
462 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
463 return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
466 if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_DOMTRUST))
468 DEBUG(0,("session_trust_account: Domain trust account %s denied by server\n",user));
469 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
470 return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT));
473 if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_SVRTRUST))
475 DEBUG(0,("session_trust_account: Server trust account %s denied by server\n",user));
476 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
477 return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT));
480 if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_WSTRUST))
482 DEBUG(4,("session_trust_account: Wksta trust account %s denied by server\n", user));
483 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
484 return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT));
488 /* don't know what to do: indicate logon failure */
489 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
490 return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
493 /****************************************************************************
494 Create a UNIX user on demand.
495 ****************************************************************************/
497 static int smb_create_user(char *unix_user)
502 pstrcpy(add_script, lp_adduser_script());
503 pstring_sub(add_script, "%u", unix_user);
504 ret = smbrun(add_script,NULL,False);
505 DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
509 /****************************************************************************
510 Delete a UNIX user on demand.
511 ****************************************************************************/
513 static int smb_delete_user(char *unix_user)
518 pstrcpy(del_script, lp_deluser_script());
519 pstring_sub(del_script, "%u", unix_user);
520 ret = smbrun(del_script,NULL,False);
521 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
525 /****************************************************************************
526 Check user is in correct domain if required
527 ****************************************************************************/
529 static BOOL check_domain_match(char *user, char *domain)
532 * If we aren't serving to trusted domains, we must make sure that
533 * the validation request comes from an account in the same domain
534 * as the Samba server
537 if (!lp_allow_trusted_domains() &&
538 !strequal(lp_workgroup(), domain) ) {
539 DEBUG(1, ("check_domain_match: Attempt to connect as user %s from domain %s denied.\n", user, domain));
546 /****************************************************************************
547 Check for a valid username and password in security=server mode.
548 ****************************************************************************/
550 static BOOL check_server_security(char *orig_user, char *domain, char *unix_user,
551 char *smb_apasswd, int smb_apasslen,
552 char *smb_ntpasswd, int smb_ntpasslen)
556 if(lp_security() != SEC_SERVER)
559 if (!check_domain_match(orig_user, domain))
562 ret = server_validate(orig_user, domain,
563 smb_apasswd, smb_apasslen,
564 smb_ntpasswd, smb_ntpasslen);
567 * User validated ok against Domain controller.
568 * If the admin wants us to try and create a UNIX
569 * user on the fly, do so.
570 * Note that we can never delete users when in server
571 * level security as we never know if it was a failure
572 * due to a bad password, or the user really doesn't exist.
574 if(lp_adduser_script() && !Get_Pwnam(unix_user,True)) {
575 smb_create_user(unix_user);
582 /****************************************************************************
583 Check for a valid username and password in security=domain mode.
584 ****************************************************************************/
586 static BOOL check_domain_security(char *orig_user, char *domain, char *unix_user,
587 char *smb_apasswd, int smb_apasslen,
588 char *smb_ntpasswd, int smb_ntpasslen)
591 BOOL user_exists = True;
593 if(lp_security() != SEC_DOMAIN)
596 if (!check_domain_match(orig_user, domain))
599 ret = domain_client_validate(orig_user, domain,
600 smb_apasswd, smb_apasslen,
601 smb_ntpasswd, smb_ntpasslen,
606 * User validated ok against Domain controller.
607 * If the admin wants us to try and create a UNIX
608 * user on the fly, do so.
610 if(user_exists && lp_adduser_script() && !Get_Pwnam(unix_user,True)) {
611 smb_create_user(unix_user);
615 * User failed to validate ok against Domain controller.
616 * If the failure was "user doesn't exist" and admin
617 * wants us to try and delete that UNIX user on the fly,
620 if(!user_exists && lp_deluser_script() && Get_Pwnam(unix_user,True)) {
621 smb_delete_user(unix_user);
628 /****************************************************************************
629 Return a bad password error configured for the correct client type.
630 ****************************************************************************/
632 static int bad_password_error(char *inbuf,char *outbuf)
634 enum remote_arch_types ra_type = get_remote_arch();
636 if(ra_type == RA_WINNT && (global_client_caps & (CAP_NT_SMBS | CAP_STATUS32 ))) {
637 SSVAL(outbuf,smb_flg2,FLAGS2_32_BIT_ERROR_CODES);
638 return(ERROR(0,0xc0000000|NT_STATUS_LOGON_FAILURE));
641 return(ERROR(ERRSRV,ERRbadpw));
644 /****************************************************************************
645 reply to a session setup command
646 ****************************************************************************/
648 int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
654 int smb_apasslen = 0;
656 int smb_ntpasslen = 0;
657 pstring smb_ntpasswd;
658 BOOL valid_nt_password = False;
662 static BOOL done_sesssetup = False;
663 BOOL doencrypt = SMBENCRYPT();
669 smb_bufsize = SVAL(inbuf,smb_vwv2);
671 if (Protocol < PROTOCOL_NT1) {
672 smb_apasslen = SVAL(inbuf,smb_vwv7);
673 if (smb_apasslen > MAX_PASS_LEN)
674 overflow_attack(smb_apasslen);
676 memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
677 smb_apasswd[smb_apasslen] = 0;
678 pstrcpy(user,smb_buf(inbuf)+smb_apasslen);
680 * Incoming user is in DOS codepage format. Convert
683 dos_to_unix(user,True);
685 if (!doencrypt && (lp_security() != SEC_SERVER)) {
686 smb_apasslen = strlen(smb_apasswd);
689 uint16 passlen1 = SVAL(inbuf,smb_vwv7);
690 uint16 passlen2 = SVAL(inbuf,smb_vwv8);
691 enum remote_arch_types ra_type = get_remote_arch();
692 char *p = smb_buf(inbuf);
694 if(global_client_caps == 0)
695 global_client_caps = IVAL(inbuf,smb_vwv11);
697 /* client_caps is used as final determination if client is NT or Win95.
698 This is needed to return the correct error codes in some
702 if(ra_type == RA_WINNT || ra_type == RA_WIN95) {
703 if(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))
704 set_remote_arch( RA_WINNT);
706 set_remote_arch( RA_WIN95);
709 if (passlen1 != 24 && passlen2 != 24)
712 if (passlen1 > MAX_PASS_LEN) {
713 overflow_attack(passlen1);
716 passlen1 = MIN(passlen1, MAX_PASS_LEN);
717 passlen2 = MIN(passlen2, MAX_PASS_LEN);
720 /* both Win95 and WinNT stuff up the password lengths for
721 non-encrypting systems. Uggh.
723 if passlen1==24 its a win95 system, and its setting the
724 password length incorrectly. Luckily it still works with the
725 default code because Win95 will null terminate the password
728 if passlen1>0 and passlen2>0 then maybe its a NT box and its
729 setting passlen2 to some random value which really stuffs
730 things up. we need to fix that one. */
732 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1)
736 if (lp_restrict_anonymous()) {
737 /* there seems to be no reason behind the differences in MS clients formatting
738 * various info like the domain, NativeOS, and NativeLanMan fields. Win95
739 * in particular seems to have an extra null byte between the username and the
740 * domain, or the password length calculation is wrong, which throws off the
741 * string extraction routines below. This makes the value of domain be the
742 * empty string, which fails the restrict anonymous check further down.
743 * This compensates for that, and allows browsing to work in mixed NT and
744 * win95 environments even when restrict anonymous is true. AAB
746 dump_data(100, p, 0x70);
747 DEBUG(9, ("passlen1=%d, passlen2=%d\n", passlen1, passlen2));
748 if (ra_type == RA_WIN95 && !passlen1 && !passlen2 && p[0] == 0 && p[1] == 0) {
749 DEBUG(0, ("restrict anonymous parameter used in a win95 environment!\n"));
750 DEBUG(0, ("client is win95 and broken passlen1 offset -- attempting fix\n"));
751 DEBUG(0, ("if win95 cilents are having difficulty browsing, you will be unable to use restrict anonymous\n"));
756 if(doencrypt || ((lp_security() == SEC_SERVER) || (lp_security() == SEC_DOMAIN))) {
757 /* Save the lanman2 password and the NT md4 password. */
758 smb_apasslen = passlen1;
759 memcpy(smb_apasswd,p,smb_apasslen);
760 smb_apasswd[smb_apasslen] = 0;
761 smb_ntpasslen = passlen2;
762 memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen);
763 smb_ntpasswd[smb_ntpasslen] = 0;
766 * Ensure the plaintext passwords are in UNIX format.
769 dos_to_unix(smb_apasswd,True);
770 dos_to_unix(smb_ntpasswd,True);
774 /* we use the first password that they gave */
775 smb_apasslen = passlen1;
776 StrnCpy(smb_apasswd,p,smb_apasslen);
778 * Ensure the plaintext password is in UNIX format.
780 dos_to_unix(smb_apasswd,True);
782 /* trim the password */
783 smb_apasslen = strlen(smb_apasswd);
785 /* wfwg sometimes uses a space instead of a null */
786 if (strequal(smb_apasswd," ")) {
792 p += passlen1 + passlen2;
794 p = skip_string(p,1);
796 * Incoming user is in DOS codepage format. Convert
799 dos_to_unix(user,True);
802 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n",
803 domain,skip_string(p,1),skip_string(p,2)));
807 DEBUG(3,("sesssetupX:name=[%s]\n",user));
809 /* If name ends in $ then I think it's asking about whether a */
810 /* computer with that name (minus the $) has access. For now */
811 /* say yes to everything ending in $. */
813 if (*user && (user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24)) {
814 return session_trust_account(conn, inbuf, outbuf, user,
815 smb_apasswd, smb_apasslen,
816 smb_ntpasswd, smb_ntpasslen);
819 if (done_sesssetup && lp_restrict_anonymous()) {
820 /* tests show that even if browsing is done over already validated connections
821 * without a username and password the domain is still provided, which it
822 * wouldn't be if it was a purely anonymous connection. So, in order to
823 * restrict anonymous, we only deny connections that have no session
824 * information. If a domain has been provided, then it's not a purely
825 * anonymous connection. AAB
827 if (!*user && !*smb_apasswd && !*domain) {
828 DEBUG(0, ("restrict anonymous is True and anonymous connection attempted. Denying access.\n"));
829 return(ERROR(ERRDOS,ERRnoaccess));
833 /* If no username is sent use the guest account */
835 pstrcpy(user,lp_guestaccount(-1));
836 /* If no user and no password then set guest flag. */
837 if( *smb_apasswd == 0)
844 * In share level security, only overwrite sesssetup_use if
845 * it's a non null-session share. Helps keep %U and %G
849 if((lp_security() != SEC_SHARE) || (*user && !guest))
850 pstrcpy(sesssetup_user,user);
852 reload_services(True);
855 * Save the username before mapping. We will use
856 * the original username sent to us for security=server
857 * and security=domain checking.
860 pstrcpy( orig_user, user);
863 * Pass the user through the NT -> unix user mapping
867 (void)map_username(user);
870 * Do any UNIX username case mangling.
872 (void)Get_Pwnam( user, True);
874 add_session_user(user);
877 * Check if the given username was the guest user with no password.
880 if(!guest && strequal(user,lp_guestaccount(-1)) && (*smb_apasswd == 0))
884 * Check with orig_user for security=server and
889 !check_server_security(orig_user, domain, user,
890 smb_apasswd, smb_apasslen,
891 smb_ntpasswd, smb_ntpasslen) &&
892 !check_domain_security(orig_user, domain, user,
893 smb_apasswd, smb_apasslen,
894 smb_ntpasswd, smb_ntpasslen) &&
895 !check_hosts_equiv(user)
900 * If we get here then the user wasn't guest and the remote
901 * authentication methods failed. Check the authentication
902 * methods on this local server.
904 * If an NT password was supplied try and validate with that
905 * first. This is superior as the passwords are mixed case
906 * 128 length unicode.
911 if(!password_ok(user, smb_ntpasswd,smb_ntpasslen,NULL))
912 DEBUG(2,("NT Password did not match for user '%s' ! Defaulting to Lanman\n", user));
914 valid_nt_password = True;
917 if (!valid_nt_password && !password_ok(user, smb_apasswd,smb_apasslen,NULL))
919 if (lp_security() >= SEC_USER)
921 if (lp_map_to_guest() == NEVER_MAP_TO_GUEST)
923 DEBUG(1,("Rejecting user '%s': authentication failed\n", user));
924 return bad_password_error(inbuf,outbuf);
927 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER)
929 if (Get_Pwnam(user,True))
931 DEBUG(1,("Rejecting user '%s': bad password\n", user));
932 return bad_password_error(inbuf,outbuf);
937 * ..else if lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
938 * Then always map to guest account - as done below.
942 if (*smb_apasswd || !Get_Pwnam(user,True))
943 pstrcpy(user,lp_guestaccount(-1));
944 DEBUG(3,("Registered username %s for guest access\n",user));
949 if (!Get_Pwnam(user,True)) {
950 DEBUG(3,("No such user %s - using guest account\n",user));
951 pstrcpy(user,lp_guestaccount(-1));
955 if (!strequal(user,lp_guestaccount(-1)) &&
956 lp_servicenumber(user) < 0)
958 int homes = lp_servicenumber(HOMES_NAME);
959 char *home = get_user_home_dir(user);
960 if (homes >= 0 && home)
961 lp_add_home(user,homes,home);
965 /* it's ok - setup a reply */
966 if (Protocol < PROTOCOL_NT1) {
967 set_message(outbuf,3,0,True);
970 set_message(outbuf,3,3,True);
972 pstrcpy(p,"Unix"); p = skip_string(p,1);
973 pstrcpy(p,"Samba "); pstrcat(p,VERSION); p = skip_string(p,1);
974 pstrcpy(p,global_myworkgroup); p = skip_string(p,1);
975 set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
976 /* perhaps grab OS version here?? */
979 /* Set the correct uid in the outgoing and incoming packets
980 We will use this on future requests to determine which
981 user we should become.
984 struct passwd *pw = Get_Pwnam(user,False);
986 DEBUG(1,("Username %s is invalid on this system\n",user));
987 return bad_password_error(inbuf,outbuf);
994 SSVAL(outbuf,smb_vwv2,1);
996 /* register the name and uid as being validated, so further connections
997 to a uid can get through without a password, on the same VC */
998 sess_vuid = register_vuid(uid,gid,user,sesssetup_user,guest);
1000 SSVAL(outbuf,smb_uid,sess_vuid);
1001 SSVAL(inbuf,smb_uid,sess_vuid);
1003 if (!done_sesssetup)
1004 max_send = MIN(max_send,smb_bufsize);
1006 DEBUG(6,("Client requested max send size of %d\n", max_send));
1008 done_sesssetup = True;
1010 return chain_reply(inbuf,outbuf,length,bufsize);
1014 /****************************************************************************
1016 ****************************************************************************/
1017 int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1023 BOOL bad_path = False;
1026 pstrcpy(name,smb_buf(inbuf) + 1);
1027 unix_convert(name,conn,0,&bad_path,&st);
1029 mode = SVAL(inbuf,smb_vwv0);
1031 if (check_name(name,conn)) {
1033 ok = S_ISDIR(st.st_mode);
1035 ok = dos_directory_exist(name,NULL);
1040 /* We special case this - as when a Windows machine
1041 is parsing a path is steps through the components
1042 one at a time - if a component fails it expects
1043 ERRbadpath, not ERRbadfile.
1047 unix_ERR_class = ERRDOS;
1048 unix_ERR_code = ERRbadpath;
1052 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
1053 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
1054 (get_remote_arch() == RA_WINNT))
1056 unix_ERR_class = ERRDOS;
1057 unix_ERR_code = ERRbaddirectory;
1061 return(UNIXERROR(ERRDOS,ERRbadpath));
1064 outsize = set_message(outbuf,0,0,True);
1066 DEBUG(3,("chkpth %s mode=%d\n", name, mode));
1072 /****************************************************************************
1074 ****************************************************************************/
1075 int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1079 SMB_STRUCT_STAT sbuf;
1084 BOOL bad_path = False;
1086 pstrcpy(fname,smb_buf(inbuf) + 1);
1088 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
1089 under WfWg - weird! */
1092 mode = aHIDDEN | aDIR;
1093 if (!CAN_WRITE(conn)) mode |= aRONLY;
1100 unix_convert(fname,conn,0,&bad_path,&sbuf);
1101 if (check_name(fname,conn))
1103 if (VALID_STAT(sbuf) || dos_stat(fname,&sbuf) == 0)
1105 mode = dos_mode(conn,fname,&sbuf);
1106 size = sbuf.st_size;
1107 mtime = sbuf.st_mtime;
1113 DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
1119 if((errno == ENOENT) && bad_path)
1121 unix_ERR_class = ERRDOS;
1122 unix_ERR_code = ERRbadpath;
1125 return(UNIXERROR(ERRDOS,ERRbadfile));
1128 outsize = set_message(outbuf,10,0,True);
1130 SSVAL(outbuf,smb_vwv0,mode);
1131 if(lp_dos_filetime_resolution(SNUM(conn)) )
1132 put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
1134 put_dos_date3(outbuf,smb_vwv1,mtime);
1135 SIVAL(outbuf,smb_vwv3,(uint32)size);
1137 if (Protocol >= PROTOCOL_NT1) {
1138 char *p = strrchr(fname,'/');
1139 uint16 flg2 = SVAL(outbuf,smb_flg2);
1141 if (!is_8_3(fname, True))
1142 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
1145 DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
1151 /****************************************************************************
1153 ****************************************************************************/
1154 int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1162 BOOL bad_path = False;
1164 pstrcpy(fname,smb_buf(inbuf) + 1);
1165 unix_convert(fname,conn,0,&bad_path,&st);
1167 mode = SVAL(inbuf,smb_vwv0);
1168 mtime = make_unix_date3(inbuf+smb_vwv1);
1170 if (VALID_STAT_OF_DIR(st) || dos_directory_exist(fname,NULL))
1172 if (check_name(fname,conn))
1173 ok = (file_chmod(conn,fname,mode,NULL) == 0);
1175 ok = set_filetime(conn,fname,mtime);
1179 if((errno == ENOENT) && bad_path)
1181 unix_ERR_class = ERRDOS;
1182 unix_ERR_code = ERRbadpath;
1185 return(UNIXERROR(ERRDOS,ERRnoaccess));
1188 outsize = set_message(outbuf,0,0,True);
1190 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
1196 /****************************************************************************
1198 ****************************************************************************/
1199 int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1202 SMB_BIG_UINT dfree,dsize,bsize;
1204 sys_disk_free(".",True,&bsize,&dfree,&dsize);
1206 outsize = set_message(outbuf,5,0,True);
1208 SSVAL(outbuf,smb_vwv0,dsize);
1209 SSVAL(outbuf,smb_vwv1,bsize/512);
1210 SSVAL(outbuf,smb_vwv2,512);
1211 SSVAL(outbuf,smb_vwv3,dfree);
1213 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
1219 /****************************************************************************
1221 Can be called from SMBsearch, SMBffirst or SMBfunique.
1222 ****************************************************************************/
1223 int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1234 BOOL finished = False;
1243 BOOL check_descend = False;
1244 BOOL expect_close = False;
1245 BOOL can_open = True;
1246 BOOL bad_path = False;
1248 *mask = *directory = *fname = 0;
1250 /* If we were called as SMBffirst then we must expect close. */
1251 if(CVAL(inbuf,smb_com) == SMBffirst)
1252 expect_close = True;
1254 outsize = set_message(outbuf,1,3,True);
1255 maxentries = SVAL(inbuf,smb_vwv0);
1256 dirtype = SVAL(inbuf,smb_vwv1);
1257 path = smb_buf(inbuf) + 1;
1258 status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
1261 /* dirtype &= ~aDIR; */
1263 DEBUG(5,("reply_search: path=%s status_len=%d\n",path,status_len));
1266 if (status_len == 0)
1270 pstrcpy(directory,smb_buf(inbuf)+1);
1271 pstrcpy(dir2,smb_buf(inbuf)+1);
1272 unix_convert(directory,conn,0,&bad_path,NULL);
1275 if (!check_name(directory,conn))
1278 p = strrchr(dir2,'/');
1290 p = strrchr(directory,'/');
1296 if (strlen(directory) == 0)
1297 pstrcpy(directory,"./");
1298 memset((char *)status,'\0',21);
1299 CVAL(status,0) = dirtype;
1303 memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
1304 memcpy(mask,status+1,11);
1306 dirtype = CVAL(status,0) & 0x1F;
1307 conn->dirptr = dptr_fetch(status+12,&dptr_num);
1310 string_set(&conn->dirpath,dptr_path(dptr_num));
1311 if (!case_sensitive)
1315 /* turn strings of spaces into a . */
1317 trim_string(mask,NULL," ");
1318 if ((p = strrchr(mask,' ')))
1323 trim_string(mask,NULL," ");
1329 /* Convert the formatted mask. (This code lives in trans2.c) */
1337 if((skip = skip_multibyte_char( *p )) != 0 )
1343 if (*p != '?' && *p != '*' && !isdoschar(*p))
1345 DEBUG(5,("Invalid char [%c] in search mask?\n",*p));
1353 if (!strchr(mask,'.') && strlen(mask)>8)
1356 fstrcpy(tmp,&mask[8]);
1362 DEBUG(5,("mask=%s directory=%s\n",mask,directory));
1366 p = smb_buf(outbuf) + 3;
1370 if (status_len == 0)
1372 dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
1377 if((errno == ENOENT) && bad_path)
1379 unix_ERR_class = ERRDOS;
1380 unix_ERR_code = ERRbadpath;
1382 return (UNIXERROR(ERRDOS,ERRnofids));
1384 return(ERROR(ERRDOS,ERRnofids));
1388 DEBUG(4,("dptr_num is %d\n",dptr_num));
1392 if ((dirtype&0x1F) == aVOLID)
1394 memcpy(p,status,21);
1395 make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
1396 dptr_fill(p+12,dptr_num);
1397 if (dptr_zero(p+12) && (status_len==0))
1401 p += DIR_STRUCT_SIZE;
1405 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1406 conn->dirpath,lp_dontdescend(SNUM(conn))));
1407 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
1408 check_descend = True;
1410 for (i=numentries;(i<maxentries) && !finished;i++)
1413 !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
1416 memcpy(p,status,21);
1417 make_dir_struct(p,mask,fname,size,mode,date);
1418 dptr_fill(p+12,dptr_num);
1421 p += DIR_STRUCT_SIZE;
1430 if (numentries == 0 || !ok)
1432 CVAL(outbuf,smb_rcls) = ERRDOS;
1433 SSVAL(outbuf,smb_err,ERRnofiles);
1434 dptr_close(&dptr_num);
1437 /* If we were called as SMBffirst with smb_search_id == NULL
1438 and no entries were found then return error and close dirptr
1441 if(ok && expect_close && numentries == 0 && status_len == 0)
1443 CVAL(outbuf,smb_rcls) = ERRDOS;
1444 SSVAL(outbuf,smb_err,ERRnofiles);
1445 /* Also close the dptr - we know it's gone */
1446 dptr_close(&dptr_num);
1449 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1450 if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique)
1451 dptr_close(&dptr_num);
1453 SSVAL(outbuf,smb_vwv0,numentries);
1454 SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
1455 CVAL(smb_buf(outbuf),0) = 5;
1456 SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
1458 if (Protocol >= PROTOCOL_NT1) {
1459 uint16 flg2 = SVAL(outbuf,smb_flg2);
1460 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
1463 outsize += DIR_STRUCT_SIZE*numentries;
1464 smb_setlen(outbuf,outsize - 4);
1466 if ((! *directory) && dptr_path(dptr_num))
1467 slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1469 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%d of %d\n",
1470 smb_fn_name(CVAL(inbuf,smb_com)),
1471 mask, directory, dirtype, numentries, maxentries ) );
1477 /****************************************************************************
1478 reply to a fclose (stop directory search)
1479 ****************************************************************************/
1480 int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1488 outsize = set_message(outbuf,1,0,True);
1489 path = smb_buf(inbuf) + 1;
1490 status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
1493 if (status_len == 0)
1494 return(ERROR(ERRSRV,ERRsrverror));
1496 memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
1498 if(dptr_fetch(status+12,&dptr_num)) {
1499 /* Close the dptr - we know it's gone */
1500 dptr_close(&dptr_num);
1503 SSVAL(outbuf,smb_vwv0,0);
1505 DEBUG(3,("search close\n"));
1511 /****************************************************************************
1513 ****************************************************************************/
1515 int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1525 SMB_STRUCT_STAT sbuf;
1526 BOOL bad_path = False;
1528 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1530 share_mode = SVAL(inbuf,smb_vwv0);
1532 pstrcpy(fname,smb_buf(inbuf)+1);
1533 unix_convert(fname,conn,0,&bad_path,NULL);
1537 return(ERROR(ERRSRV,ERRnofids));
1539 if (!check_name(fname,conn))
1541 if((errno == ENOENT) && bad_path)
1543 unix_ERR_class = ERRDOS;
1544 unix_ERR_code = ERRbadpath;
1547 return(UNIXERROR(ERRDOS,ERRnoaccess));
1550 unixmode = unix_mode(conn,aARCH);
1552 open_file_shared(fsp,conn,fname,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1553 unixmode, oplock_request,&rmode,NULL);
1557 if((errno == ENOENT) && bad_path)
1559 unix_ERR_class = ERRDOS;
1560 unix_ERR_code = ERRbadpath;
1563 return(UNIXERROR(ERRDOS,ERRnoaccess));
1566 if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
1567 close_file(fsp,False);
1568 return(ERROR(ERRDOS,ERRnoaccess));
1571 size = sbuf.st_size;
1572 fmode = dos_mode(conn,fname,&sbuf);
1573 mtime = sbuf.st_mtime;
1576 DEBUG(3,("attempt to open a directory %s\n",fname));
1577 close_file(fsp,False);
1578 return(ERROR(ERRDOS,ERRnoaccess));
1581 outsize = set_message(outbuf,7,0,True);
1582 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1583 SSVAL(outbuf,smb_vwv1,fmode);
1584 if(lp_dos_filetime_resolution(SNUM(conn)) )
1585 put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
1587 put_dos_date3(outbuf,smb_vwv2,mtime);
1588 SIVAL(outbuf,smb_vwv4,(uint32)size);
1589 SSVAL(outbuf,smb_vwv6,rmode);
1591 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1592 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1595 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1596 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1601 /****************************************************************************
1602 reply to an open and X
1603 ****************************************************************************/
1604 int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1607 int smb_mode = SVAL(inbuf,smb_vwv3);
1608 int smb_attr = SVAL(inbuf,smb_vwv5);
1609 /* Breakout the oplock request bits so we can set the
1610 reply bits separately. */
1611 BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
1612 BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1613 BOOL oplock_request = ex_oplock_request | core_oplock_request;
1615 int open_flags = SVAL(inbuf,smb_vwv2);
1616 int smb_sattr = SVAL(inbuf,smb_vwv4);
1617 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
1619 int smb_ofun = SVAL(inbuf,smb_vwv8);
1622 int fmode=0,mtime=0,rmode=0;
1623 SMB_STRUCT_STAT sbuf;
1625 BOOL bad_path = False;
1628 /* If it's an IPC, pass off the pipe handler. */
1629 if (IS_IPC(conn) && lp_nt_pipe_support())
1630 return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
1632 /* XXXX we need to handle passed times, sattr and flags */
1634 pstrcpy(fname,smb_buf(inbuf));
1635 unix_convert(fname,conn,0,&bad_path,NULL);
1639 return(ERROR(ERRSRV,ERRnofids));
1641 if (!check_name(fname,conn))
1643 if((errno == ENOENT) && bad_path)
1645 unix_ERR_class = ERRDOS;
1646 unix_ERR_code = ERRbadpath;
1649 return(UNIXERROR(ERRDOS,ERRnoaccess));
1652 unixmode = unix_mode(conn,smb_attr | aARCH);
1654 open_file_shared(fsp,conn,fname,smb_mode,smb_ofun,unixmode,
1655 oplock_request, &rmode,&smb_action);
1659 if((errno == ENOENT) && bad_path)
1661 unix_ERR_class = ERRDOS;
1662 unix_ERR_code = ERRbadpath;
1665 return(UNIXERROR(ERRDOS,ERRnoaccess));
1668 if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
1669 close_file(fsp,False);
1670 return(ERROR(ERRDOS,ERRnoaccess));
1673 size = sbuf.st_size;
1674 fmode = dos_mode(conn,fname,&sbuf);
1675 mtime = sbuf.st_mtime;
1677 close_file(fsp,False);
1678 return(ERROR(ERRDOS,ERRnoaccess));
1681 /* If the caller set the extended oplock request bit
1682 and we granted one (by whatever means) - set the
1683 correct bit for extended oplock reply.
1686 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1687 smb_action |= EXTENDED_OPLOCK_GRANTED;
1690 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1691 smb_action |= EXTENDED_OPLOCK_GRANTED;
1694 /* If the caller set the core oplock request bit
1695 and we granted one (by whatever means) - set the
1696 correct bit for core oplock reply.
1699 if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1700 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1703 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1704 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1707 set_message(outbuf,15,0,True);
1708 SSVAL(outbuf,smb_vwv2,fsp->fnum);
1709 SSVAL(outbuf,smb_vwv3,fmode);
1710 if(lp_dos_filetime_resolution(SNUM(conn)) )
1711 put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
1713 put_dos_date3(outbuf,smb_vwv4,mtime);
1714 SIVAL(outbuf,smb_vwv6,(uint32)size);
1715 SSVAL(outbuf,smb_vwv8,rmode);
1716 SSVAL(outbuf,smb_vwv11,smb_action);
1718 return chain_reply(inbuf,outbuf,length,bufsize);
1722 /****************************************************************************
1723 reply to a SMBulogoffX
1724 ****************************************************************************/
1725 int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1727 uint16 vuid = SVAL(inbuf,smb_uid);
1728 user_struct *vuser = get_valid_user_struct(vuid);
1731 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
1734 /* in user level security we are supposed to close any files
1735 open by this user */
1736 if ((vuser != 0) && (lp_security() != SEC_SHARE)) {
1737 file_close_user(vuid);
1740 invalidate_vuid(vuid);
1742 set_message(outbuf,2,0,True);
1744 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
1746 return chain_reply(inbuf,outbuf,length,bufsize);
1750 /****************************************************************************
1751 reply to a mknew or a create
1752 ****************************************************************************/
1753 int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1761 BOOL bad_path = False;
1763 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1765 com = SVAL(inbuf,smb_com);
1767 createmode = SVAL(inbuf,smb_vwv0);
1768 pstrcpy(fname,smb_buf(inbuf)+1);
1769 unix_convert(fname,conn,0,&bad_path,NULL);
1771 if (createmode & aVOLID)
1773 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
1776 unixmode = unix_mode(conn,createmode);
1780 return(ERROR(ERRSRV,ERRnofids));
1782 if (!check_name(fname,conn))
1784 if((errno == ENOENT) && bad_path)
1786 unix_ERR_class = ERRDOS;
1787 unix_ERR_code = ERRbadpath;
1790 return(UNIXERROR(ERRDOS,ERRnoaccess));
1795 /* We should fail if file exists. */
1796 ofun = FILE_CREATE_IF_NOT_EXIST;
1800 /* SMBcreate - Create if file doesn't exist, truncate if it does. */
1801 ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
1804 /* Open file in dos compatibility share mode. */
1805 open_file_shared(fsp,conn,fname,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1806 ofun, unixmode, oplock_request, NULL, NULL);
1810 if((errno == ENOENT) && bad_path)
1812 unix_ERR_class = ERRDOS;
1813 unix_ERR_code = ERRbadpath;
1816 return(UNIXERROR(ERRDOS,ERRnoaccess));
1819 outsize = set_message(outbuf,1,0,True);
1820 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1822 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1823 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1826 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1827 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1829 DEBUG( 2, ( "new file %s\n", fname ) );
1830 DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n",
1831 fname, fsp->fd_ptr->fd, createmode, (int)unixmode ) );
1837 /****************************************************************************
1838 reply to a create temporary file
1839 ****************************************************************************/
1840 int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1847 BOOL bad_path = False;
1849 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1851 createmode = SVAL(inbuf,smb_vwv0);
1852 pstrcpy(fname,smb_buf(inbuf)+1);
1853 pstrcat(fname,"/TMXXXXXX");
1854 unix_convert(fname,conn,0,&bad_path,NULL);
1856 unixmode = unix_mode(conn,createmode);
1860 return(ERROR(ERRSRV,ERRnofids));
1862 if (!check_name(fname,conn))
1864 if((errno == ENOENT) && bad_path)
1866 unix_ERR_class = ERRDOS;
1867 unix_ERR_code = ERRbadpath;
1870 return(UNIXERROR(ERRDOS,ERRnoaccess));
1873 pstrcpy(fname2,(char *)smbd_mktemp(fname));
1875 /* Open file in dos compatibility share mode. */
1876 /* We should fail if file exists. */
1877 open_file_shared(fsp,conn,fname2,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1878 (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unixmode, oplock_request, NULL, NULL);
1882 if((errno == ENOENT) && bad_path)
1884 unix_ERR_class = ERRDOS;
1885 unix_ERR_code = ERRbadpath;
1888 return(UNIXERROR(ERRDOS,ERRnoaccess));
1891 outsize = set_message(outbuf,1,2 + strlen(fname2),True);
1892 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1893 CVAL(smb_buf(outbuf),0) = 4;
1894 pstrcpy(smb_buf(outbuf) + 1,fname2);
1896 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1897 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1900 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1901 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1903 DEBUG( 2, ( "created temp file %s\n", fname2 ) );
1904 DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
1905 fname2, fsp->fd_ptr->fd, createmode, (int)unixmode ) );
1911 /*******************************************************************
1912 check if a user is allowed to delete a file
1913 ********************************************************************/
1914 static BOOL can_delete(char *fname,connection_struct *conn, int dirtype)
1916 SMB_STRUCT_STAT sbuf;
1919 if (!CAN_WRITE(conn)) return(False);
1921 if (dos_lstat(fname,&sbuf) != 0) return(False);
1922 fmode = dos_mode(conn,fname,&sbuf);
1923 if (fmode & aDIR) return(False);
1924 if (!lp_delete_readonly(SNUM(conn))) {
1925 if (fmode & aRONLY) return(False);
1927 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
1929 if (!check_file_sharing(conn,fname,False)) return(False);
1933 /****************************************************************************
1935 ****************************************************************************/
1937 int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1946 int error = ERRnoaccess;
1949 BOOL bad_path = False;
1952 *directory = *mask = 0;
1954 dirtype = SVAL(inbuf,smb_vwv0);
1956 pstrcpy(name,smb_buf(inbuf) + 1);
1958 DEBUG(3,("reply_unlink : %s\n",name));
1960 rc = unix_convert(name,conn,0,&bad_path,NULL);
1962 p = strrchr(name,'/');
1964 pstrcpy(directory,"./");
1968 pstrcpy(directory,name);
1973 * We should only check the mangled cache
1974 * here if unix_convert failed. This means
1975 * that the path in 'mask' doesn't exist
1976 * on the file system and so we need to look
1977 * for a possible mangle. This patch from
1978 * Tine Smukavec <valentin.smukavec@hermes.si>.
1981 if (!rc && is_mangled(mask))
1982 check_mangled_cache( mask );
1984 has_wild = strchr(mask,'*') || strchr(mask,'?');
1987 pstrcat(directory,"/");
1988 pstrcat(directory,mask);
1989 if (can_delete(directory,conn,dirtype) && !dos_unlink(directory))
1992 exists = dos_file_exist(directory,NULL);
1994 void *dirptr = NULL;
1997 if (check_name(directory,conn))
1998 dirptr = OpenDir(conn, directory, True);
2000 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
2001 the pattern matches against the long name, otherwise the short name
2002 We don't implement this yet XXXX
2009 if (strequal(mask,"????????.???"))
2012 while ((dname = ReadDirName(dirptr)))
2015 pstrcpy(fname,dname);
2017 if(!mask_match(fname, mask, case_sensitive, False)) continue;
2019 error = ERRnoaccess;
2020 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
2021 if (!can_delete(fname,conn,dirtype)) continue;
2022 if (!dos_unlink(fname)) count++;
2023 DEBUG(3,("reply_unlink : doing unlink on %s\n",fname));
2031 return(ERROR(ERRDOS,error));
2034 if((errno == ENOENT) && bad_path)
2036 unix_ERR_class = ERRDOS;
2037 unix_ERR_code = ERRbadpath;
2039 return(UNIXERROR(ERRDOS,error));
2043 outsize = set_message(outbuf,0,0,True);
2049 /****************************************************************************
2050 reply to a readbraw (core+ protocol)
2051 ****************************************************************************/
2053 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
2055 size_t maxcount,mincount;
2058 char *header = outbuf;
2063 * Special check if an oplock break has been issued
2064 * and the readraw request croses on the wire, we must
2065 * return a zero length response here.
2068 if(global_oplock_break)
2070 _smb_setlen(header,0);
2071 transfer_file(0,Client,(SMB_OFF_T)0,header,4,0);
2072 DEBUG(5,("readbraw - oplock break finished\n"));
2076 fsp = file_fsp(inbuf,smb_vwv0);
2078 if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
2080 * fsp could be NULL here so use the value from the packet. JRA.
2082 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
2083 _smb_setlen(header,0);
2084 transfer_file(0,Client,(SMB_OFF_T)0,header,4,0);
2088 CHECK_FSP(fsp,conn);
2090 flush_write_cache(fsp, READRAW_FLUSH);
2092 startpos = IVAL(inbuf,smb_vwv1);
2093 if(CVAL(inbuf,smb_wct) == 10) {
2095 * This is a large offset (64 bit) read.
2097 #ifdef LARGE_SMB_OFF_T
2099 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
2101 #else /* !LARGE_SMB_OFF_T */
2104 * Ensure we haven't been sent a >32 bit offset.
2107 if(IVAL(inbuf,smb_vwv8) != 0) {
2108 DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
2109 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
2110 _smb_setlen(header,0);
2111 transfer_file(0,Client,(SMB_OFF_T)0,header,4,0);
2115 #endif /* LARGE_SMB_OFF_T */
2118 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n",
2119 (double)startpos ));
2120 _smb_setlen(header,0);
2121 transfer_file(0,Client,(SMB_OFF_T)0,header,4,0);
2125 maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
2126 mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
2128 /* ensure we don't overrun the packet size */
2129 maxcount = MIN(65535,maxcount);
2130 maxcount = MAX(mincount,maxcount);
2132 if (!is_locked(fsp,conn,maxcount,startpos, F_RDLCK))
2134 SMB_OFF_T size = fsp->size;
2135 SMB_OFF_T sizeneeded = startpos + maxcount;
2137 if (size < sizeneeded)
2140 if (sys_fstat(fsp->fd_ptr->fd,&st) == 0)
2142 if (!fsp->can_write)
2146 nread = MIN(maxcount,(size - startpos));
2149 if (nread < mincount)
2152 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n",
2153 fsp->fnum, (double)startpos,
2154 (int)maxcount, (int)mincount, (int)nread ) );
2158 BOOL seek_fail = False;
2160 _smb_setlen(header,nread);
2162 #if USE_READ_PREDICTION
2163 if (!fsp->can_write)
2164 predict = read_predict(fsp->fd_ptr->fd,startpos,header+4,NULL,nread);
2165 #endif /* USE_READ_PREDICTION */
2167 if ((nread-predict) > 0) {
2168 if(seek_file(fsp,startpos + predict) == -1) {
2169 DEBUG(0,("reply_readbraw: ERROR: seek_file failed.\n"));
2176 ret = (ssize_t)transfer_file(fsp->fd_ptr->fd,Client,
2177 (SMB_OFF_T)(nread-predict),header,4+predict,
2182 DEBUG(0,("ERROR: file read failure on %s at %d for %d bytes (%d)\n",
2183 fsp->fsp_name,startpos,nread,ret));
2185 #else /* UNSAFE_READRAW */
2186 ret = read_file(fsp,header+4,startpos,nread);
2187 if (ret < mincount) ret = 0;
2189 _smb_setlen(header,ret);
2190 transfer_file(0,Client,0,header,4+ret,0);
2191 #endif /* UNSAFE_READRAW */
2193 DEBUG(5,("readbraw finished\n"));
2198 /****************************************************************************
2199 reply to a lockread (core+ protocol)
2200 ****************************************************************************/
2201 int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
2210 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2212 CHECK_FSP(fsp,conn);
2216 numtoread = SVAL(inbuf,smb_vwv1);
2217 startpos = IVAL(inbuf,smb_vwv2);
2219 outsize = set_message(outbuf,5,3,True);
2220 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
2221 data = smb_buf(outbuf) + 3;
2224 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
2225 * protocol request that predates the read/write lock concept.
2226 * Thus instead of asking for a read lock here we need to ask
2227 * for a write lock. JRA.
2230 if(!do_lock( fsp, conn, numtoread, startpos, F_WRLCK, &eclass, &ecode)) {
2231 if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) {
2233 * A blocking lock was requested. Package up
2234 * this smb into a queued request and push it
2235 * onto the blocking lock queue.
2237 if(push_blocking_lock_request(inbuf, length, -1, 0))
2240 return (ERROR(eclass,ecode));
2243 nread = read_file(fsp,data,startpos,numtoread);
2246 return(UNIXERROR(ERRDOS,ERRnoaccess));
2249 SSVAL(outbuf,smb_vwv0,nread);
2250 SSVAL(outbuf,smb_vwv5,nread+3);
2251 SSVAL(smb_buf(outbuf),1,nread);
2253 DEBUG( 3, ( "lockread fnum=%d num=%d nread=%d\n",
2254 fsp->fnum, (int)numtoread, (int)nread ) );
2260 /****************************************************************************
2262 ****************************************************************************/
2264 int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2271 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2273 CHECK_FSP(fsp,conn);
2277 numtoread = SVAL(inbuf,smb_vwv1);
2278 startpos = IVAL(inbuf,smb_vwv2);
2280 outsize = set_message(outbuf,5,3,True);
2281 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
2282 data = smb_buf(outbuf) + 3;
2284 if (is_locked(fsp,conn,numtoread,startpos, F_RDLCK))
2285 return(ERROR(ERRDOS,ERRlock));
2288 nread = read_file(fsp,data,startpos,numtoread);
2291 return(UNIXERROR(ERRDOS,ERRnoaccess));
2294 SSVAL(outbuf,smb_vwv0,nread);
2295 SSVAL(outbuf,smb_vwv5,nread+3);
2296 CVAL(smb_buf(outbuf),0) = 1;
2297 SSVAL(smb_buf(outbuf),1,nread);
2299 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
2300 fsp->fnum, (int)numtoread, (int)nread ) );
2306 /****************************************************************************
2307 reply to a read and X
2308 ****************************************************************************/
2309 int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2311 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2312 SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3);
2313 size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
2314 size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
2318 /* If it's an IPC, pass off the pipe handler. */
2320 return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
2322 CHECK_FSP(fsp,conn);
2326 set_message(outbuf,12,0,True);
2327 data = smb_buf(outbuf);
2329 if(CVAL(inbuf,smb_wct) == 12) {
2330 #ifdef LARGE_SMB_OFF_T
2332 * This is a large offset (64 bit) read.
2334 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
2336 #else /* !LARGE_SMB_OFF_T */
2339 * Ensure we haven't been sent a >32 bit offset.
2342 if(IVAL(inbuf,smb_vwv10) != 0) {
2343 DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
2344 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) ));
2345 return(ERROR(ERRDOS,ERRbadaccess));
2348 #endif /* LARGE_SMB_OFF_T */
2352 if (is_locked(fsp,conn,smb_maxcnt,startpos, F_RDLCK))
2353 return(ERROR(ERRDOS,ERRlock));
2354 nread = read_file(fsp,data,startpos,smb_maxcnt);
2357 return(UNIXERROR(ERRDOS,ERRnoaccess));
2359 SSVAL(outbuf,smb_vwv5,nread);
2360 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
2361 SSVAL(smb_buf(outbuf),-2,nread);
2363 DEBUG( 3, ( "readX fnum=%d min=%d max=%d nread=%d\n",
2364 fsp->fnum, (int)smb_mincnt, (int)smb_maxcnt, (int)nread ) );
2366 return chain_reply(inbuf,outbuf,length,bufsize);
2369 /****************************************************************************
2370 reply to a writebraw (core+ or LANMAN1.0 protocol)
2371 ****************************************************************************/
2373 int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2376 ssize_t total_written=0;
2377 size_t numtowrite=0;
2382 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2385 CHECK_FSP(fsp,conn);
2389 tcount = IVAL(inbuf,smb_vwv1);
2390 startpos = IVAL(inbuf,smb_vwv3);
2391 write_through = BITSETW(inbuf+smb_vwv7,0);
2393 /* We have to deal with slightly different formats depending
2394 on whether we are using the core+ or lanman1.0 protocol */
2395 if(Protocol <= PROTOCOL_COREPLUS) {
2396 numtowrite = SVAL(smb_buf(inbuf),-2);
2397 data = smb_buf(inbuf);
2399 numtowrite = SVAL(inbuf,smb_vwv10);
2400 data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
2403 /* force the error type */
2404 CVAL(inbuf,smb_com) = SMBwritec;
2405 CVAL(outbuf,smb_com) = SMBwritec;
2407 if (is_locked(fsp,conn,tcount,startpos, F_WRLCK))
2408 return(ERROR(ERRDOS,ERRlock));
2411 nwritten = write_file(fsp,data,startpos,numtowrite);
2413 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
2414 fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
2416 if (nwritten < numtowrite)
2417 return(UNIXERROR(ERRHRD,ERRdiskfull));
2419 total_written = nwritten;
2421 /* Return a message to the redirector to tell it
2422 to send more bytes */
2423 CVAL(outbuf,smb_com) = SMBwritebraw;
2424 SSVALS(outbuf,smb_vwv0,-1);
2425 outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
2426 send_smb(Client,outbuf);
2428 /* Now read the raw data into the buffer and write it */
2429 if (read_smb_length(Client,inbuf,SMB_SECONDARY_WAIT) == -1) {
2430 exit_server("secondary writebraw failed");
2433 /* Even though this is not an smb message, smb_len
2434 returns the generic length of an smb message */
2435 numtowrite = smb_len(inbuf);
2437 if (tcount > nwritten+numtowrite) {
2438 DEBUG(3,("Client overestimated the write %d %d %d\n",
2439 (int)tcount,(int)nwritten,(int)numtowrite));
2442 nwritten = transfer_file(Client,fsp->fd_ptr->fd,(SMB_OFF_T)numtowrite,NULL,0,
2444 total_written += nwritten;
2446 /* Set up outbuf to return the correct return */
2447 outsize = set_message(outbuf,1,0,True);
2448 CVAL(outbuf,smb_com) = SMBwritec;
2449 SSVAL(outbuf,smb_vwv0,total_written);
2451 if (nwritten < (ssize_t)numtowrite) {
2452 CVAL(outbuf,smb_rcls) = ERRHRD;
2453 SSVAL(outbuf,smb_err,ERRdiskfull);
2456 if (lp_syncalways(SNUM(conn)) || write_through)
2457 sync_file(conn,fsp);
2459 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
2460 fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
2462 /* we won't return a status if write through is not selected - this
2463 follows what WfWg does */
2464 if (!write_through && total_written==tcount)
2470 /****************************************************************************
2471 reply to a writeunlock (core+)
2472 ****************************************************************************/
2474 int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2476 ssize_t nwritten = -1;
2482 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2485 CHECK_FSP(fsp,conn);
2489 numtowrite = SVAL(inbuf,smb_vwv1);
2490 startpos = IVAL(inbuf,smb_vwv2);
2491 data = smb_buf(inbuf) + 3;
2493 if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
2494 return(ERROR(ERRDOS,ERRlock));
2496 /* The special X/Open SMB protocol handling of
2497 zero length writes is *NOT* done for
2502 nwritten = write_file(fsp,data,startpos,numtowrite);
2504 if (lp_syncalways(SNUM(conn)))
2505 sync_file(conn,fsp);
2507 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
2508 return(UNIXERROR(ERRDOS,ERRnoaccess));
2510 if(!do_unlock(fsp, conn, numtowrite, startpos, &eclass, &ecode))
2511 return(ERROR(eclass,ecode));
2513 outsize = set_message(outbuf,1,0,True);
2515 SSVAL(outbuf,smb_vwv0,nwritten);
2517 DEBUG( 3, ( "writeunlock fnum=%d num=%d wrote=%d\n",
2518 fsp->fnum, (int)numtowrite, (int)nwritten ) );
2523 /****************************************************************************
2525 ****************************************************************************/
2526 int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
2529 ssize_t nwritten = -1;
2532 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2535 /* If it's an IPC, pass off the pipe handler. */
2537 return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
2539 CHECK_FSP(fsp,conn);
2543 numtowrite = SVAL(inbuf,smb_vwv1);
2544 startpos = IVAL(inbuf,smb_vwv2);
2545 data = smb_buf(inbuf) + 3;
2547 if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
2548 return(ERROR(ERRDOS,ERRlock));
2550 /* X/Open SMB protocol says that if smb_vwv1 is
2551 zero then the file size should be extended or
2552 truncated to the size given in smb_vwv[2-3] */
2553 if(numtowrite == 0) {
2554 if((nwritten = set_filelen(fsp->fd_ptr->fd, (SMB_OFF_T)startpos)) >= 0)
2555 set_filelen_write_cache(fsp, startpos);
2557 nwritten = write_file(fsp,data,startpos,numtowrite);
2559 if (lp_syncalways(SNUM(conn)))
2560 sync_file(conn,fsp);
2562 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
2563 return(UNIXERROR(ERRDOS,ERRnoaccess));
2565 outsize = set_message(outbuf,1,0,True);
2567 SSVAL(outbuf,smb_vwv0,nwritten);
2569 if (nwritten < (ssize_t)numtowrite) {
2570 CVAL(outbuf,smb_rcls) = ERRHRD;
2571 SSVAL(outbuf,smb_err,ERRdiskfull);
2574 DEBUG(3,("write fnum=%d num=%d wrote=%d\n",
2575 fsp->fnum, (int)numtowrite, (int)nwritten));
2581 /****************************************************************************
2582 reply to a write and X
2583 ****************************************************************************/
2584 int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2586 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2587 SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3);
2588 size_t numtowrite = SVAL(inbuf,smb_vwv10);
2589 BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
2590 ssize_t nwritten = -1;
2591 int smb_doff = SVAL(inbuf,smb_vwv11);
2594 /* If it's an IPC, pass off the pipe handler. */
2596 return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
2598 CHECK_FSP(fsp,conn);
2602 data = smb_base(inbuf) + smb_doff;
2604 if(CVAL(inbuf,smb_wct) == 14) {
2605 #ifdef LARGE_SMB_OFF_T
2607 * This is a large offset (64 bit) write.
2609 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
2611 #else /* !LARGE_SMB_OFF_T */
2614 * Ensure we haven't been sent a >32 bit offset.
2617 if(IVAL(inbuf,smb_vwv12) != 0) {
2618 DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
2619 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
2620 return(ERROR(ERRDOS,ERRbadaccess));
2623 #endif /* LARGE_SMB_OFF_T */
2626 if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
2627 return(ERROR(ERRDOS,ERRlock));
2629 /* X/Open SMB protocol says that, unlike SMBwrite
2630 if the length is zero then NO truncation is
2631 done, just a write of zero. To truncate a file,
2636 nwritten = write_file(fsp,data,startpos,numtowrite);
2638 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
2639 return(UNIXERROR(ERRDOS,ERRnoaccess));
2641 set_message(outbuf,6,0,True);
2643 SSVAL(outbuf,smb_vwv2,nwritten);
2645 if (nwritten < (ssize_t)numtowrite) {
2646 CVAL(outbuf,smb_rcls) = ERRHRD;
2647 SSVAL(outbuf,smb_err,ERRdiskfull);
2650 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
2651 fsp->fnum, (int)numtowrite, (int)nwritten));
2653 if (lp_syncalways(SNUM(conn)) || write_through)
2654 sync_file(conn,fsp);
2656 return chain_reply(inbuf,outbuf,length,bufsize);
2660 /****************************************************************************
2662 ****************************************************************************/
2664 int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2670 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2672 CHECK_FSP(fsp,conn);
2675 flush_write_cache(fsp, SEEK_FLUSH);
2677 mode = SVAL(inbuf,smb_vwv1) & 3;
2678 startpos = IVALS(inbuf,smb_vwv2);
2681 case 0: umode = SEEK_SET; break;
2682 case 1: umode = SEEK_CUR; break;
2683 case 2: umode = SEEK_END; break;
2685 umode = SEEK_SET; break;
2688 if((res = sys_lseek(fsp->fd_ptr->fd,startpos,umode)) == -1) {
2690 * Check for the special case where a seek before the start
2691 * of the file sets the offset to zero. Added in the CIFS spec,
2695 if(errno == EINVAL) {
2696 SMB_OFF_T current_pos = startpos;
2698 if(umode == SEEK_CUR) {
2700 if((current_pos = sys_lseek(fsp->fd_ptr->fd,0,SEEK_CUR)) == -1)
2701 return(UNIXERROR(ERRDOS,ERRnoaccess));
2703 current_pos += startpos;
2705 } else if (umode == SEEK_END) {
2707 SMB_STRUCT_STAT sbuf;
2709 if(sys_fstat( fsp->fd_ptr->fd, &sbuf) == -1)
2710 return(UNIXERROR(ERRDOS,ERRnoaccess));
2712 current_pos += sbuf.st_size;
2716 res = sys_lseek(fsp->fd_ptr->fd,0,SEEK_SET);
2720 return(UNIXERROR(ERRDOS,ERRnoaccess));
2725 outsize = set_message(outbuf,2,0,True);
2726 SIVAL(outbuf,smb_vwv0,res);
2728 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
2729 fsp->fnum, (double)startpos, (double)res, mode));
2734 /****************************************************************************
2736 ****************************************************************************/
2738 int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2740 int outsize = set_message(outbuf,0,0,True);
2741 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2744 CHECK_FSP(fsp,conn);
2749 file_sync_all(conn);
2751 sync_file(conn,fsp);
2754 DEBUG(3,("flush\n"));
2759 /****************************************************************************
2761 ****************************************************************************/
2762 int reply_exit(connection_struct *conn,
2763 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2765 int outsize = set_message(outbuf,0,0,True);
2766 DEBUG(3,("exit\n"));
2772 /****************************************************************************
2773 Reply to a close - has to deal with closing a directory opened by NT SMB's.
2774 ****************************************************************************/
2775 int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
2780 int32 eclass = 0, err = 0;
2781 files_struct *fsp = NULL;
2783 outsize = set_message(outbuf,0,0,True);
2785 /* If it's an IPC, pass off to the pipe handler. */
2787 return reply_pipe_close(conn, inbuf,outbuf);
2789 fsp = file_fsp(inbuf,smb_vwv0);
2792 * We can only use CHECK_FSP if we know it's not a directory.
2795 if(!fsp || !fsp->open || (fsp->conn != conn))
2796 return(ERROR(ERRDOS,ERRbadfid));
2798 if(HAS_CACHED_ERROR(fsp)) {
2799 eclass = fsp->wbmpx_ptr->wr_errclass;
2800 err = fsp->wbmpx_ptr->wr_error;
2803 if(fsp->is_directory || fsp->stat_open) {
2805 * Special case - close NT SMB directory or stat file
2808 DEBUG(3,("close %s fnum=%d\n", fsp->is_directory ? "directory" : "stat file open", fsp->fnum));
2809 close_file(fsp,True);
2812 * Close ordinary file.
2817 * If there was a modify time outstanding,
2818 * try and set it here.
2820 if(fsp->pending_modtime)
2821 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
2824 * Now take care of any time sent in the close.
2826 mtime = make_unix_date3(inbuf+smb_vwv1);
2828 /* try and set the date */
2829 set_filetime(conn, fsp->fsp_name,mtime);
2831 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
2832 fsp->fd_ptr ? fsp->fd_ptr->fd : -1, fsp->fnum,
2833 conn->num_files_open));
2836 * close_file() returns the unix errno if an error
2837 * was detected on close - normally this is due to
2838 * a disk full error. If not then it was probably an I/O error.
2841 if((close_err = close_file(fsp,True)) != 0) {
2843 return (UNIXERROR(ERRHRD,ERRgeneral));
2847 /* We have a cached error */
2849 return(ERROR(eclass,err));
2855 /****************************************************************************
2856 reply to a writeclose (Core+ protocol)
2857 ****************************************************************************/
2859 int reply_writeclose(connection_struct *conn,
2860 char *inbuf,char *outbuf, int size, int dum_buffsize)
2863 ssize_t nwritten = -1;
2869 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2871 CHECK_FSP(fsp,conn);
2875 numtowrite = SVAL(inbuf,smb_vwv1);
2876 startpos = IVAL(inbuf,smb_vwv2);
2877 mtime = make_unix_date3(inbuf+smb_vwv4);
2878 data = smb_buf(inbuf) + 1;
2880 if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
2881 return(ERROR(ERRDOS,ERRlock));
2883 nwritten = write_file(fsp,data,startpos,numtowrite);
2885 set_filetime(conn, fsp->fsp_name,mtime);
2887 close_err = close_file(fsp,True);
2889 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
2890 fsp->fnum, (int)numtowrite, (int)nwritten,
2891 conn->num_files_open));
2894 return(UNIXERROR(ERRDOS,ERRnoaccess));
2896 if(close_err != 0) {
2898 return(UNIXERROR(ERRHRD,ERRgeneral));
2901 outsize = set_message(outbuf,1,0,True);
2903 SSVAL(outbuf,smb_vwv0,nwritten);
2908 /****************************************************************************
2910 ****************************************************************************/
2911 int reply_lock(connection_struct *conn,
2912 char *inbuf,char *outbuf, int length, int dum_buffsize)
2914 int outsize = set_message(outbuf,0,0,True);
2915 SMB_OFF_T count,offset;
2918 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2920 CHECK_FSP(fsp,conn);
2923 count = IVAL(inbuf,smb_vwv1);
2924 offset = IVAL(inbuf,smb_vwv3);
2926 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2927 fsp->fd_ptr->fd, fsp->fnum, (double)offset, (double)count));
2929 if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode)) {
2930 if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) {
2932 * A blocking lock was requested. Package up
2933 * this smb into a queued request and push it
2934 * onto the blocking lock queue.
2936 if(push_blocking_lock_request(inbuf, length, -1, 0))
2939 return (ERROR(eclass,ecode));
2946 /****************************************************************************
2948 ****************************************************************************/
2950 int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
2952 int outsize = set_message(outbuf,0,0,True);
2953 SMB_OFF_T count,offset;
2956 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2958 CHECK_FSP(fsp,conn);
2961 count = IVAL(inbuf,smb_vwv1);
2962 offset = IVAL(inbuf,smb_vwv3);
2964 if(!do_unlock(fsp, conn, count, offset, &eclass, &ecode))
2965 return (ERROR(eclass,ecode));
2967 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2968 fsp->fd_ptr->fd, fsp->fnum, (double)offset, (double)count ) );
2974 /****************************************************************************
2976 ****************************************************************************/
2977 int reply_tdis(connection_struct *conn,
2978 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2980 int outsize = set_message(outbuf,0,0,True);
2983 vuid = SVAL(inbuf,smb_uid);
2986 DEBUG(4,("Invalid connection in tdis\n"));
2987 return(ERROR(ERRSRV,ERRinvnid));
2992 close_cnum(conn,vuid);
2999 /****************************************************************************
3001 ****************************************************************************/
3002 int reply_echo(connection_struct *conn,
3003 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3005 int smb_reverb = SVAL(inbuf,smb_vwv0);
3007 int data_len = smb_buflen(inbuf);
3008 int outsize = set_message(outbuf,1,data_len,True);
3010 /* copy any incoming data back out */
3012 memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
3014 if (smb_reverb > 100) {
3015 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
3019 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
3020 SSVAL(outbuf,smb_vwv0,seq_num);
3022 smb_setlen(outbuf,outsize - 4);
3024 send_smb(Client,outbuf);
3027 DEBUG(3,("echo %d times\n", smb_reverb));
3035 /****************************************************************************
3036 reply to a printopen
3037 ****************************************************************************/
3038 int reply_printopen(connection_struct *conn,
3039 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3046 *fname = *fname2 = 0;
3048 if (!CAN_PRINT(conn))
3049 return(ERROR(ERRDOS,ERRnoaccess));
3054 pstrcpy(s,smb_buf(inbuf)+1);
3057 if (!(isalnum((int)*p) || strchr("._-",*p)))
3062 if (strlen(s) > 10) s[10] = 0;
3064 slprintf(fname,sizeof(fname)-1, "%s.XXXXXX",s);
3069 return(ERROR(ERRSRV,ERRnofids));
3071 pstrcpy(fname2,(char *)smbd_mktemp(fname));
3073 if (!check_name(fname2,conn)) {
3075 return(ERROR(ERRDOS,ERRnoaccess));
3078 /* Open for exclusive use, write only. */
3079 open_file_shared(fsp,conn,fname2, SET_DENY_MODE(DENY_ALL)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
3080 (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unix_mode(conn,0), 0, NULL, NULL);
3084 return(UNIXERROR(ERRDOS,ERRnoaccess));
3087 /* force it to be a print file */
3088 fsp->print_file = True;
3090 outsize = set_message(outbuf,1,0,True);
3091 SSVAL(outbuf,smb_vwv0,fsp->fnum);
3093 DEBUG(3,("openprint %s fd=%d fnum=%d\n",
3094 fname2, fsp->fd_ptr->fd, fsp->fnum));
3100 /****************************************************************************
3101 reply to a printclose
3102 ****************************************************************************/
3103 int reply_printclose(connection_struct *conn,
3104 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3106 int outsize = set_message(outbuf,0,0,True);
3107 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3110 CHECK_FSP(fsp,conn);
3113 if (!CAN_PRINT(conn))
3114 return(ERROR(ERRDOS,ERRnoaccess));
3116 DEBUG(3,("printclose fd=%d fnum=%d\n",
3117 fsp->fd_ptr->fd,fsp->fnum));
3119 close_err = close_file(fsp,True);
3121 if(close_err != 0) {
3123 return(UNIXERROR(ERRHRD,ERRgeneral));
3130 /****************************************************************************
3131 reply to a printqueue
3132 ****************************************************************************/
3133 int reply_printqueue(connection_struct *conn,
3134 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3136 int outsize = set_message(outbuf,2,3,True);
3137 int max_count = SVAL(inbuf,smb_vwv0);
3138 int start_index = SVAL(inbuf,smb_vwv1);
3140 /* we used to allow the client to get the cnum wrong, but that
3141 is really quite gross and only worked when there was only
3142 one printer - I think we should now only accept it if they
3143 get it right (tridge) */
3144 if (!CAN_PRINT(conn))
3145 return(ERROR(ERRDOS,ERRnoaccess));
3147 SSVAL(outbuf,smb_vwv0,0);
3148 SSVAL(outbuf,smb_vwv1,0);
3149 CVAL(smb_buf(outbuf),0) = 1;
3150 SSVAL(smb_buf(outbuf),1,0);
3152 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
3153 start_index, max_count));
3156 print_queue_struct *queue = NULL;
3157 char *p = smb_buf(outbuf) + 3;
3158 int count = get_printqueue(SNUM(conn), conn,&queue,NULL);
3159 int num_to_get = ABS(max_count);
3160 int first = (max_count>0?start_index:start_index+max_count+1);
3166 num_to_get = MIN(num_to_get,count-first);
3169 for (i=first;i<first+num_to_get;i++) {
3170 put_dos_date2(p,0,queue[i].time);
3171 CVAL(p,4) = (queue[i].status==LPQ_PRINTING?2:3);
3172 SSVAL(p,5,printjob_encode(SNUM(conn),
3174 SIVAL(p,7,queue[i].size);
3176 StrnCpy(p+12,queue[i].user,16);
3181 outsize = set_message(outbuf,2,28*count+3,False);
3182 SSVAL(outbuf,smb_vwv0,count);
3183 SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
3184 CVAL(smb_buf(outbuf),0) = 1;
3185 SSVAL(smb_buf(outbuf),1,28*count);
3188 if (queue) free(queue);
3190 DEBUG(3,("%d entries returned in queue\n",count));
3197 /****************************************************************************
3198 reply to a printwrite
3199 ****************************************************************************/
3200 int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3203 int outsize = set_message(outbuf,0,0,True);
3205 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3207 if (!CAN_PRINT(conn))
3208 return(ERROR(ERRDOS,ERRnoaccess));
3210 CHECK_FSP(fsp,conn);
3214 numtowrite = SVAL(smb_buf(inbuf),1);
3215 data = smb_buf(inbuf) + 3;
3217 if (write_file(fsp,data,-1,numtowrite) != numtowrite)
3218 return(UNIXERROR(ERRDOS,ERRnoaccess));
3220 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
3226 /****************************************************************************
3228 ****************************************************************************/
3229 int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3232 int outsize,ret= -1;
3233 BOOL bad_path = False;
3235 pstrcpy(directory,smb_buf(inbuf) + 1);
3236 unix_convert(directory,conn,0,&bad_path,NULL);
3238 if (check_name(directory, conn))
3239 ret = dos_mkdir(directory,unix_mode(conn,aDIR));
3243 if((errno == ENOENT) && bad_path)
3245 unix_ERR_class = ERRDOS;
3246 unix_ERR_code = ERRbadpath;
3248 return(UNIXERROR(ERRDOS,ERRnoaccess));
3251 outsize = set_message(outbuf,0,0,True);
3253 DEBUG( 3, ( "mkdir %s ret=%d\n", directory, ret ) );
3258 /****************************************************************************
3259 Static function used by reply_rmdir to delete an entire directory
3261 ****************************************************************************/
3263 static BOOL recursive_rmdir(char *directory)
3267 void *dirptr = OpenDir(NULL, directory, False);
3272 while((dname = ReadDirName(dirptr)))
3277 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3280 /* Construct the full name. */
3281 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
3287 pstrcpy(fullname, directory);
3288 pstrcat(fullname, "/");
3289 pstrcat(fullname, dname);
3291 if(dos_lstat(fullname, &st) != 0)
3297 if(st.st_mode & S_IFDIR)
3299 if(recursive_rmdir(fullname)!=0)
3304 if(dos_rmdir(fullname) != 0)
3310 else if(dos_unlink(fullname) != 0)
3320 /****************************************************************************
3321 The internals of the rmdir code - called elsewhere.
3322 ****************************************************************************/
3324 BOOL rmdir_internals(connection_struct *conn, char *directory)
3328 ok = (dos_rmdir(directory) == 0);
3329 if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn)))
3332 * Check to see if the only thing in this directory are
3333 * vetoed files/directories. If so then delete them and
3334 * retry. If we fail to delete any of them (and we *don't*
3335 * do a recursive delete) then fail the rmdir.
3337 BOOL all_veto_files = True;
3339 void *dirptr = OpenDir(conn, directory, False);
3343 int dirpos = TellDir(dirptr);
3344 while ((dname = ReadDirName(dirptr)))
3346 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3348 if(!IS_VETO_PATH(conn, dname))
3350 all_veto_files = False;
3356 SeekDir(dirptr,dirpos);
3357 while ((dname = ReadDirName(dirptr)))
3362 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3365 /* Construct the full name. */
3366 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
3371 pstrcpy(fullname, directory);
3372 pstrcat(fullname, "/");
3373 pstrcat(fullname, dname);
3375 if(dos_lstat(fullname, &st) != 0)
3377 if(st.st_mode & S_IFDIR)
3379 if(lp_recursive_veto_delete(SNUM(conn)))
3381 if(recursive_rmdir(fullname) != 0)
3384 if(dos_rmdir(fullname) != 0)
3387 else if(dos_unlink(fullname) != 0)
3391 /* Retry the rmdir */
3392 ok = (dos_rmdir(directory) == 0);
3402 DEBUG(3,("rmdir_internals: couldn't remove directory %s : %s\n",
3403 directory,strerror(errno)));
3408 /****************************************************************************
3410 ****************************************************************************/
3412 int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3417 BOOL bad_path = False;
3419 pstrcpy(directory,smb_buf(inbuf) + 1);
3420 unix_convert(directory,conn, NULL,&bad_path,NULL);
3422 if (check_name(directory,conn))
3424 dptr_closepath(directory,SVAL(inbuf,smb_pid));
3425 ok = rmdir_internals(conn, directory);
3430 if((errno == ENOENT) && bad_path)
3432 unix_ERR_class = ERRDOS;
3433 unix_ERR_code = ERRbadpath;
3435 return(UNIXERROR(ERRDOS,ERRbadpath));
3438 outsize = set_message(outbuf,0,0,True);
3440 DEBUG( 3, ( "rmdir %s\n", directory ) );
3446 /*******************************************************************
3447 resolve wildcards in a filename rename
3448 ********************************************************************/
3449 static BOOL resolve_wildcards(char *name1,char *name2)
3451 fstring root1,root2;
3455 name1 = strrchr(name1,'/');
3456 name2 = strrchr(name2,'/');
3458 if (!name1 || !name2) return(False);
3460 fstrcpy(root1,name1);
3461 fstrcpy(root2,name2);
3462 p = strrchr(root1,'.');
3469 p = strrchr(root2,'.');
3501 pstrcpy(name2,root2);
3504 pstrcat(name2,ext2);
3510 /*******************************************************************
3511 check if a user is allowed to rename a file
3512 ********************************************************************/
3513 static BOOL can_rename(char *fname,connection_struct *conn)
3515 SMB_STRUCT_STAT sbuf;
3517 if (!CAN_WRITE(conn)) return(False);
3519 if (dos_lstat(fname,&sbuf) != 0) return(False);
3520 if (!check_file_sharing(conn,fname,True)) return(False);
3525 /****************************************************************************
3526 The guts of the rename command, split out so it may be called by the NT SMB
3528 ****************************************************************************/
3529 int rename_internals(connection_struct *conn,
3530 char *inbuf, char *outbuf, char *name,
3531 char *newname, BOOL replace_if_exists)
3535 pstring newname_last_component;
3538 BOOL bad_path1 = False;
3539 BOOL bad_path2 = False;
3541 int error = ERRnoaccess;
3545 *directory = *mask = 0;
3547 rc = unix_convert(name,conn,0,&bad_path1,NULL);
3548 unix_convert(newname,conn,newname_last_component,&bad_path2,NULL);
3551 * Split the old name into directory and last component
3552 * strings. Note that unix_convert may have stripped off a
3553 * leading ./ from both name and newname if the rename is
3554 * at the root of the share. We need to make sure either both
3555 * name and newname contain a / character or neither of them do
3556 * as this is checked in resolve_wildcards().
3559 p = strrchr(name,'/');
3561 pstrcpy(directory,".");
3565 pstrcpy(directory,name);
3567 *p = '/'; /* Replace needed for exceptional test below. */
3571 * We should only check the mangled cache
3572 * here if unix_convert failed. This means
3573 * that the path in 'mask' doesn't exist
3574 * on the file system and so we need to look
3575 * for a possible mangle. This patch from
3576 * Tine Smukavec <valentin.smukavec@hermes.si>.
3579 if (!rc && is_mangled(mask))
3580 check_mangled_cache( mask );
3582 has_wild = strchr(mask,'*') || strchr(mask,'?');
3586 * No wildcards - just process the one file.
3588 BOOL is_short_name = is_8_3(name, True);
3590 /* Add a terminating '/' to the directory name. */
3591 pstrcat(directory,"/");
3592 pstrcat(directory,mask);
3594 /* Ensure newname contains a '/' also */
3595 if(strrchr(newname,'/') == 0) {
3598 pstrcpy(tmpstr, "./");
3599 pstrcat(tmpstr, newname);
3600 pstrcpy(newname, tmpstr);
3603 DEBUG(3,("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",
3604 case_sensitive, case_preserve, short_case_preserve, directory,
3605 newname, newname_last_component, is_short_name));
3608 * Check for special case with case preserving and not
3609 * case sensitive, if directory and newname are identical,
3610 * and the old last component differs from the original
3611 * last component only by case, then we should allow
3612 * the rename (user is trying to change the case of the
3615 if((case_sensitive == False) &&
3616 (((case_preserve == True) &&
3617 (is_short_name == False)) ||
3618 ((short_case_preserve == True) &&
3619 (is_short_name == True))) &&
3620 strcsequal(directory, newname)) {
3621 pstring newname_modified_last_component;
3624 * Get the last component of the modified name.
3625 * Note that we guarantee that newname contains a '/'
3628 p = strrchr(newname,'/');
3629 pstrcpy(newname_modified_last_component,p+1);
3631 if(strcsequal(newname_modified_last_component,
3632 newname_last_component) == False) {
3634 * Replace the modified last component with
3637 pstrcpy(p+1, newname_last_component);
3641 if(replace_if_exists) {
3643 * NT SMB specific flag - rename can overwrite
3644 * file with the same name so don't check for
3647 if(resolve_wildcards(directory,newname) &&
3648 can_rename(directory,conn) &&
3649 !dos_rename(directory,newname))
3652 if (resolve_wildcards(directory,newname) &&
3653 can_rename(directory,conn) &&
3654 !dos_file_exist(newname,NULL) &&
3655 !dos_rename(directory,newname))
3659 DEBUG(3,("rename_internals: %s doing rename on %s -> %s\n",(count != 0) ? "succeeded" : "failed",
3660 directory,newname));
3662 if (!count) exists = dos_file_exist(directory,NULL);
3663 if (!count && exists && dos_file_exist(newname,NULL)) {
3669 * Wildcards - process each file that matches.
3671 void *dirptr = NULL;
3675 if (check_name(directory,conn))
3676 dirptr = OpenDir(conn, directory, True);
3681 if (strequal(mask,"????????.???"))
3684 while ((dname = ReadDirName(dirptr))) {
3686 pstrcpy(fname,dname);
3688 if(!mask_match(fname, mask, case_sensitive, False))
3691 error = ERRnoaccess;
3692 slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname);
3693 if (!can_rename(fname,conn)) {
3694 DEBUG(6,("rename %s refused\n", fname));
3697 pstrcpy(destname,newname);
3699 if (!resolve_wildcards(fname,destname)) {
3700 DEBUG(6,("resolve_wildcards %s %s failed\n", fname, destname));
3704 if (!replace_if_exists && dos_file_exist(destname,NULL)) {
3705 DEBUG(6,("dos_file_exist %s\n", destname));
3710 if (!dos_rename(fname,destname))
3712 DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
3720 return(ERROR(ERRDOS,error));
3722 if((errno == ENOENT) && (bad_path1 || bad_path2)) {
3723 unix_ERR_class = ERRDOS;
3724 unix_ERR_code = ERRbadpath;
3726 return(UNIXERROR(ERRDOS,error));
3733 /****************************************************************************
3735 ****************************************************************************/
3737 int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3743 pstrcpy(name,smb_buf(inbuf) + 1);
3744 pstrcpy(newname,smb_buf(inbuf) + 3 + strlen(name));
3746 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
3748 outsize = rename_internals(conn, inbuf, outbuf, name, newname, False);
3750 outsize = set_message(outbuf,0,0,True);
3755 /*******************************************************************
3756 copy a file as part of a reply_copy
3757 ******************************************************************/
3759 static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
3760 int count,BOOL target_is_directory, int *err_ret)
3765 files_struct *fsp1,*fsp2;
3770 pstrcpy(dest,dest1);
3771 if (target_is_directory) {
3772 char *p = strrchr(src,'/');
3781 if (!dos_file_exist(src,&st))
3788 open_file_shared(fsp1,conn,src,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
3789 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
3796 if (!target_is_directory && count)
3801 close_file(fsp1,False);
3804 open_file_shared(fsp2,conn,dest,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
3805 ofun,st.st_mode,0,&Access,&action);
3808 close_file(fsp1,False);
3813 if ((ofun&3) == 1) {
3814 if(sys_lseek(fsp2->fd_ptr->fd,0,SEEK_END) == -1) {
3815 DEBUG(0,("copy_file: error - sys_lseek returned error %s\n",
3818 * Stop the copy from occurring.
3826 ret = transfer_file(fsp1->fd_ptr->fd,
3827 fsp2->fd_ptr->fd,st.st_size,NULL,0,0);
3829 close_file(fsp1,False);
3831 * As we are opening fsp1 read-only we only expect
3832 * an error on close on fsp2 if we are out of space.
3833 * Thus we don't look at the error return from the
3836 *err_ret = close_file(fsp2,False);
3838 return(ret == (SMB_OFF_T)st.st_size);
3843 /****************************************************************************
3844 reply to a file copy.
3845 ****************************************************************************/
3846 int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3851 pstring mask,newname;
3854 int error = ERRnoaccess;
3858 int tid2 = SVAL(inbuf,smb_vwv0);
3859 int ofun = SVAL(inbuf,smb_vwv1);
3860 int flags = SVAL(inbuf,smb_vwv2);
3861 BOOL target_is_directory=False;
3862 BOOL bad_path1 = False;
3863 BOOL bad_path2 = False;
3866 *directory = *mask = 0;
3868 pstrcpy(name,smb_buf(inbuf));
3869 pstrcpy(newname,smb_buf(inbuf) + 1 + strlen(name));
3871 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
3873 if (tid2 != conn->cnum) {
3874 /* can't currently handle inter share copies XXXX */
3875 DEBUG(3,("Rejecting inter-share copy\n"));
3876 return(ERROR(ERRSRV,ERRinvdevice));
3879 rc = unix_convert(name,conn,0,&bad_path1,NULL);
3880 unix_convert(newname,conn,0,&bad_path2,NULL);
3882 target_is_directory = dos_directory_exist(newname,NULL);
3884 if ((flags&1) && target_is_directory) {
3885 return(ERROR(ERRDOS,ERRbadfile));
3888 if ((flags&2) && !target_is_directory) {
3889 return(ERROR(ERRDOS,ERRbadpath));
3892 if ((flags&(1<<5)) && dos_directory_exist(name,NULL)) {
3893 /* wants a tree copy! XXXX */
3894 DEBUG(3,("Rejecting tree copy\n"));
3895 return(ERROR(ERRSRV,ERRerror));
3898 p = strrchr(name,'/');
3900 pstrcpy(directory,"./");
3904 pstrcpy(directory,name);
3909 * We should only check the mangled cache
3910 * here if unix_convert failed. This means
3911 * that the path in 'mask' doesn't exist
3912 * on the file system and so we need to look
3913 * for a possible mangle. This patch from
3914 * Tine Smukavec <valentin.smukavec@hermes.si>.
3917 if (!rc && is_mangled(mask))
3918 check_mangled_cache( mask );
3920 has_wild = strchr(mask,'*') || strchr(mask,'?');
3923 pstrcat(directory,"/");
3924 pstrcat(directory,mask);
3925 if (resolve_wildcards(directory,newname) &&
3926 copy_file(directory,newname,conn,ofun,
3927 count,target_is_directory,&err)) count++;
3930 return(UNIXERROR(ERRHRD,ERRgeneral));
3932 if (!count) exists = dos_file_exist(directory,NULL);
3934 void *dirptr = NULL;
3938 if (check_name(directory,conn))
3939 dirptr = OpenDir(conn, directory, True);
3944 if (strequal(mask,"????????.???"))
3947 while ((dname = ReadDirName(dirptr))) {
3949 pstrcpy(fname,dname);
3951 if(!mask_match(fname, mask, case_sensitive, False))
3954 error = ERRnoaccess;
3955 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
3956 pstrcpy(destname,newname);
3957 if (resolve_wildcards(fname,destname) &&
3958 copy_file(fname,destname,conn,ofun,
3959 count,target_is_directory,&err)) count++;
3960 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
3968 /* Error on close... */
3970 return(UNIXERROR(ERRHRD,ERRgeneral));
3974 return(ERROR(ERRDOS,error));
3977 if((errno == ENOENT) && (bad_path1 || bad_path2))
3979 unix_ERR_class = ERRDOS;
3980 unix_ERR_code = ERRbadpath;
3982 return(UNIXERROR(ERRDOS,error));
3986 outsize = set_message(outbuf,1,0,True);
3987 SSVAL(outbuf,smb_vwv0,count);
3992 /****************************************************************************
3994 ****************************************************************************/
3995 int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4003 if (!CAN_SETDIR(snum))
4004 return(ERROR(ERRDOS,ERRnoaccess));
4006 pstrcpy(newdir,smb_buf(inbuf) + 1);
4009 if (strlen(newdir) == 0) {
4012 ok = dos_directory_exist(newdir,NULL);
4014 string_set(&conn->connectpath,newdir);
4019 return(ERROR(ERRDOS,ERRbadpath));
4021 outsize = set_message(outbuf,0,0,True);
4022 CVAL(outbuf,smb_reh) = CVAL(inbuf,smb_reh);
4024 DEBUG(3,("setdir %s\n", newdir));
4029 /****************************************************************************
4030 Get a lock count, dealing with large count requests.
4031 ****************************************************************************/
4033 SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, BOOL *err)
4035 SMB_OFF_T count = 0;
4039 if(!large_file_format) {
4040 count = (SMB_OFF_T)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
4043 #if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS)
4045 count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
4046 ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
4048 #else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
4051 * NT4.x seems to be broken in that it sends large file
4052 * lockingX calls even if the CAP_LARGE_FILES was *not*
4053 * negotiated. For boxes without large file locks truncate the
4054 * lock count by dropping the top 32 bits.
4057 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
4058 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
4059 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
4060 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
4061 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
4064 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
4066 * Before we error out, see if we can sensibly map the top bits
4067 * down to the lower bits - or lose the top bits if they are all 1's.
4068 * It seems that NT has this horrible bug where it will send 64 bit
4069 * lock requests even if told not to. JRA.
4072 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) == (uint32)0xFFFFFFFF)
4073 count = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset));
4074 else if (IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) == (uint32)0xFFFFFFFF)
4075 count = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
4078 DEBUG(0,("get_lock_count: Error : a large file count (%x << 32 | %x) was sent and we don't \
4079 support large counts.\n", (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
4080 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
4083 return (SMB_OFF_T)-1;
4087 count = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
4089 #endif /* LARGE_SMB_OFF_T */
4094 /****************************************************************************
4095 Get a lock offset, dealing with large offset requests.
4096 ****************************************************************************/
4098 SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
4100 SMB_OFF_T offset = 0;
4104 if(!large_file_format) {
4105 offset = (SMB_OFF_T)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
4108 #if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS)
4110 offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
4111 ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
4113 #else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
4116 * NT4.x seems to be broken in that it sends large file
4117 * lockingX calls even if the CAP_LARGE_FILES was *not*
4118 * negotiated. For boxes without large file locks mangle the
4119 * lock offset by mapping the top 32 bits onto the lower 32.
4122 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
4123 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
4124 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
4127 if((new_low = map_lock_offset(high, low)) == 0) {
4129 return (SMB_OFF_T)-1;
4132 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
4133 (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
4134 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
4135 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
4138 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0){
4140 * Before we error out, see if we can sensibly map the top bits
4141 * down to the lower bits - or lose the top bits if they are all 1's.
4142 * It seems that NT has this horrible bug where it will send 64 bit
4143 * lock requests even if told not to. JRA.
4146 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)) == (uint32)0xFFFFFFFF)
4147 offset = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
4148 else if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) == (uint32)0xFFFFFFFF)
4149 offset = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
4152 DEBUG(0,("get_lock_count: Error : a large file offset (%x << 32 | %x) was sent and we don't \
4153 support large offsets.\n", (unsigned int)IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)),
4154 (unsigned int)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)) ));
4157 return (SMB_OFF_T)-1;
4161 offset = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
4163 #endif /* LARGE_SMB_OFF_T */
4168 /****************************************************************************
4169 reply to a lockingX request
4170 ****************************************************************************/
4172 int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
4174 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
4175 unsigned char locktype = CVAL(inbuf,smb_vwv3);
4177 unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
4179 uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
4180 uint16 num_locks = SVAL(inbuf,smb_vwv7);
4181 SMB_OFF_T count = 0, offset = 0;
4182 int32 lock_timeout = IVAL(inbuf,smb_vwv4);
4185 uint32 ecode=0, dummy2;
4186 int eclass=0, dummy1;
4187 BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
4190 CHECK_FSP(fsp,conn);
4193 data = smb_buf(inbuf);
4195 /* Check if this is an oplock break on a file
4196 we have granted an oplock on.
4198 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE))
4200 DEBUG(5,("reply_lockingX: oplock break reply from client for fnum = %d\n",
4204 * Make sure we have granted an exclusive or batch oplock on this file.
4207 if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
4209 DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
4210 no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
4212 /* if this is a pure oplock break request then don't send a reply */
4213 if (num_locks == 0 && num_ulocks == 0)
4216 return ERROR(ERRDOS,ERRlock);
4219 if (remove_oplock(fsp) == False) {
4220 DEBUG(0,("reply_lockingX: error in removing oplock on file %s\n",
4224 /* if this is a pure oplock break request then don't send a reply */
4225 if (num_locks == 0 && num_ulocks == 0)
4227 /* Sanity check - ensure a pure oplock break is not a
4229 if(CVAL(inbuf,smb_vwv0) != 0xff)
4230 DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
4231 (unsigned int)CVAL(inbuf,smb_vwv0) ));
4236 /* Data now points at the beginning of the list
4237 of smb_unlkrng structs */
4238 for(i = 0; i < (int)num_ulocks; i++) {
4239 count = get_lock_count( data, i, large_file_format, &err1);
4240 offset = get_lock_offset( data, i, large_file_format, &err2);
4243 * There is no error code marked "stupid client bug".... :-).
4246 return ERROR(ERRDOS,ERRnoaccess);
4248 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for file %s\n",
4249 (double)offset, (double)count, fsp->fsp_name ));
4251 if(!do_unlock(fsp,conn,count,offset,&eclass, &ecode))
4252 return ERROR(eclass,ecode);
4255 /* Setup the timeout in seconds. */
4256 lock_timeout = ((lock_timeout == -1) ? -1 : lock_timeout/1000);
4258 /* Now do any requested locks */
4259 data += ((large_file_format ? 20 : 10)*num_ulocks);
4261 /* Data now points at the beginning of the list
4262 of smb_lkrng structs */
4264 for(i = 0; i < (int)num_locks; i++) {
4265 count = get_lock_count( data, i, large_file_format, &err1);
4266 offset = get_lock_offset( data, i, large_file_format, &err2);
4269 * There is no error code marked "stupid client bug".... :-).
4272 return ERROR(ERRDOS,ERRnoaccess);
4274 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for file %s\n",
4275 (double)offset, (double)count, fsp->fsp_name ));
4277 if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
4279 if((ecode == ERRlock) && (lock_timeout != 0) && lp_blocking_locks(SNUM(conn))) {
4281 * A blocking lock was requested. Package up
4282 * this smb into a queued request and push it
4283 * onto the blocking lock queue.
4285 if(push_blocking_lock_request(inbuf, length, lock_timeout, i))
4292 /* If any of the above locks failed, then we must unlock
4293 all of the previous locks (X/Open spec). */
4294 if(i != num_locks && num_locks != 0) {
4295 for(; i >= 0; i--) {
4296 count = get_lock_count( data, i, large_file_format, &err1);
4297 offset = get_lock_offset( data, i, large_file_format, &err2);
4300 * There is no error code marked "stupid client bug".... :-).
4303 return ERROR(ERRDOS,ERRnoaccess);
4305 do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
4307 return ERROR(eclass,ecode);
4310 set_message(outbuf,2,0,True);
4312 DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
4313 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
4315 return chain_reply(inbuf,outbuf,length,bufsize);
4319 /****************************************************************************
4320 reply to a SMBreadbmpx (read block multiplex) request
4321 ****************************************************************************/
4322 int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
4333 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4335 /* this function doesn't seem to work - disable by default */
4337 return(ERROR(ERRSRV,ERRuseSTD));
4339 outsize = set_message(outbuf,8,0,True);
4341 CHECK_FSP(fsp,conn);
4345 startpos = IVAL(inbuf,smb_vwv1);
4346 maxcount = SVAL(inbuf,smb_vwv3);
4348 data = smb_buf(outbuf);
4349 pad = ((long)data)%4;
4350 if (pad) pad = 4 - pad;
4353 max_per_packet = bufsize-(outsize+pad);
4357 if (is_locked(fsp,conn,maxcount,startpos, F_RDLCK))
4358 return(ERROR(ERRDOS,ERRlock));
4362 size_t N = MIN(max_per_packet,tcount-total_read);
4364 nread = read_file(fsp,data,startpos,N);
4366 if (nread <= 0) nread = 0;
4368 if (nread < (ssize_t)N)
4369 tcount = total_read + nread;
4371 set_message(outbuf,8,nread,False);
4372 SIVAL(outbuf,smb_vwv0,startpos);
4373 SSVAL(outbuf,smb_vwv2,tcount);
4374 SSVAL(outbuf,smb_vwv6,nread);
4375 SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
4377 send_smb(Client,outbuf);
4379 total_read += nread;
4382 while (total_read < (ssize_t)tcount);
4387 /****************************************************************************
4388 reply to a SMBwritebmpx (write block multiplex primary) request
4389 ****************************************************************************/
4391 int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4394 ssize_t nwritten = -1;
4401 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4403 CHECK_FSP(fsp,conn);
4407 tcount = SVAL(inbuf,smb_vwv1);
4408 startpos = IVAL(inbuf,smb_vwv3);
4409 write_through = BITSETW(inbuf+smb_vwv7,0);
4410 numtowrite = SVAL(inbuf,smb_vwv10);
4411 smb_doff = SVAL(inbuf,smb_vwv11);
4413 data = smb_base(inbuf) + smb_doff;
4415 /* If this fails we need to send an SMBwriteC response,
4416 not an SMBwritebmpx - set this up now so we don't forget */
4417 CVAL(outbuf,smb_com) = SMBwritec;
4419 if (is_locked(fsp,conn,tcount,startpos,F_WRLCK))
4420 return(ERROR(ERRDOS,ERRlock));
4422 nwritten = write_file(fsp,data,startpos,numtowrite);
4424 if(lp_syncalways(SNUM(conn)) || write_through)
4425 sync_file(conn,fsp);
4427 if(nwritten < (ssize_t)numtowrite)
4428 return(UNIXERROR(ERRHRD,ERRdiskfull));
4430 /* If the maximum to be written to this file
4431 is greater than what we just wrote then set
4432 up a secondary struct to be attached to this
4433 fd, we will use this to cache error messages etc. */
4434 if((ssize_t)tcount > nwritten)
4436 write_bmpx_struct *wbms;
4437 if(fsp->wbmpx_ptr != NULL)
4438 wbms = fsp->wbmpx_ptr; /* Use an existing struct */
4440 wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
4443 DEBUG(0,("Out of memory in reply_readmpx\n"));
4444 return(ERROR(ERRSRV,ERRnoresource));
4446 wbms->wr_mode = write_through;
4447 wbms->wr_discard = False; /* No errors yet */
4448 wbms->wr_total_written = nwritten;
4449 wbms->wr_errclass = 0;
4451 fsp->wbmpx_ptr = wbms;
4454 /* We are returning successfully, set the message type back to
4456 CVAL(outbuf,smb_com) = SMBwriteBmpx;
4458 outsize = set_message(outbuf,1,0,True);
4460 SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
4462 DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
4463 fsp->fnum, (int)numtowrite, (int)nwritten ) );
4465 if (write_through && tcount==nwritten) {
4466 /* we need to send both a primary and a secondary response */
4467 smb_setlen(outbuf,outsize - 4);
4468 send_smb(Client,outbuf);
4470 /* now the secondary */
4471 outsize = set_message(outbuf,1,0,True);
4472 CVAL(outbuf,smb_com) = SMBwritec;
4473 SSVAL(outbuf,smb_vwv0,nwritten);
4480 /****************************************************************************
4481 reply to a SMBwritebs (write block multiplex secondary) request
4482 ****************************************************************************/
4483 int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4486 ssize_t nwritten = -1;
4493 write_bmpx_struct *wbms;
4494 BOOL send_response = False;
4495 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4497 CHECK_FSP(fsp,conn);
4500 tcount = SVAL(inbuf,smb_vwv1);
4501 startpos = IVAL(inbuf,smb_vwv2);
4502 numtowrite = SVAL(inbuf,smb_vwv6);
4503 smb_doff = SVAL(inbuf,smb_vwv7);
4505 data = smb_base(inbuf) + smb_doff;
4507 /* We need to send an SMBwriteC response, not an SMBwritebs */
4508 CVAL(outbuf,smb_com) = SMBwritec;
4510 /* This fd should have an auxiliary struct attached,
4511 check that it does */
4512 wbms = fsp->wbmpx_ptr;
4513 if(!wbms) return(-1);
4515 /* If write through is set we can return errors, else we must
4517 write_through = wbms->wr_mode;
4519 /* Check for an earlier error */
4520 if(wbms->wr_discard)
4521 return -1; /* Just discard the packet */
4523 nwritten = write_file(fsp,data,startpos,numtowrite);
4525 if(lp_syncalways(SNUM(conn)) || write_through)
4526 sync_file(conn,fsp);
4528 if (nwritten < (ssize_t)numtowrite)
4532 /* We are returning an error - we can delete the aux struct */
4533 if (wbms) free((char *)wbms);
4534 fsp->wbmpx_ptr = NULL;
4535 return(ERROR(ERRHRD,ERRdiskfull));
4537 return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
4540 /* Increment the total written, if this matches tcount
4541 we can discard the auxiliary struct (hurrah !) and return a writeC */
4542 wbms->wr_total_written += nwritten;
4543 if(wbms->wr_total_written >= tcount)
4547 outsize = set_message(outbuf,1,0,True);
4548 SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
4549 send_response = True;
4553 fsp->wbmpx_ptr = NULL;
4563 /****************************************************************************
4564 reply to a SMBsetattrE
4565 ****************************************************************************/
4567 int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4569 struct utimbuf unix_times;
4571 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4573 outsize = set_message(outbuf,0,0,True);
4575 CHECK_FSP(fsp,conn);
4578 /* Convert the DOS times into unix times. Ignore create
4579 time as UNIX can't set this.
4581 unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
4582 unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
4585 * Patch from Ray Frush <frush@engr.colostate.edu>
4586 * Sometimes times are sent as zero - ignore them.
4589 if ((unix_times.actime == 0) && (unix_times.modtime == 0))
4591 /* Ignore request */
4594 dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
4595 dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
4599 else if ((unix_times.actime != 0) && (unix_times.modtime == 0))
4601 /* set modify time = to access time if modify time was 0 */
4602 unix_times.modtime = unix_times.actime;
4605 /* Set the date on this file */
4606 if(file_utime(conn, fsp->fsp_name, &unix_times))
4607 return(ERROR(ERRDOS,ERRnoaccess));
4609 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
4610 fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
4616 /****************************************************************************
4617 reply to a SMBgetattrE
4618 ****************************************************************************/
4620 int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
4622 SMB_STRUCT_STAT sbuf;
4625 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4627 outsize = set_message(outbuf,11,0,True);
4629 CHECK_FSP(fsp,conn);
4632 /* Do an fstat on this file */
4633 if(sys_fstat(fsp->fd_ptr->fd, &sbuf))
4634 return(UNIXERROR(ERRDOS,ERRnoaccess));
4636 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
4638 /* Convert the times into dos times. Set create
4639 date to be last modify date as UNIX doesn't save
4641 put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
4642 put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
4643 put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
4646 SIVAL(outbuf,smb_vwv6,0);
4647 SIVAL(outbuf,smb_vwv8,0);
4651 SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
4652 SIVAL(outbuf,smb_vwv8,SMB_ROUNDUP(sbuf.st_size,1024));
4654 SSVAL(outbuf,smb_vwv10, mode);
4656 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));