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 fstring global_myworkgroup;
43 extern int global_oplock_break;
44 uint32 global_client_caps = 0;
47 /****************************************************************************
48 report a possible attack via the password buffer overflow bug
49 ****************************************************************************/
50 static void overflow_attack(int len)
54 dbgtext( "ERROR: Invalid password length %d.\n", len );
55 dbgtext( "Your machine may be under attack by someone " );
56 dbgtext( "attempting to exploit an old bug.\n" );
57 dbgtext( "Attack was from IP = %s.\n", client_addr(Client) );
59 exit_server("possible attack");
63 /****************************************************************************
64 does _both_ nt->unix and unix->unix username remappings.
65 ****************************************************************************/
66 static void map_nt_and_unix_username(const char *domain, char *user)
72 * Pass the user through the NT -> unix user mapping
76 if (lp_server_role() != ROLE_DOMAIN_NONE)
78 memset(nt_username, 0, sizeof(nt_username));
81 slprintf(nt_username, sizeof(nt_username)-1, "%s\\%s",
86 fstrcpy(nt_username, user);
89 if (lookupsmbpwntnam(nt_username, &gmep))
91 fstrcpy(user, gmep.unix_name);
96 * Pass the user through the unix -> unix user mapping
100 (void)map_username(user);
103 * Do any UNIX username case mangling.
105 (void)Get_Pwnam( user, True);
108 /****************************************************************************
109 reply to an special message
110 ****************************************************************************/
111 int reply_special(char *inbuf,char *outbuf)
114 int msg_type = CVAL(inbuf,0);
115 int msg_flags = CVAL(inbuf,1);
117 extern fstring remote_machine;
118 extern fstring local_machine;
124 bzero(outbuf,smb_size);
126 smb_setlen(outbuf,0);
128 DEBUG(20,("NBT message\n"));
129 dump_data(20, inbuf, smb_len(inbuf));
132 case 0x81: /* session request */
133 CVAL(outbuf,0) = 0x82;
135 if (name_len(inbuf+4) > 50 ||
136 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
137 DEBUG(0,("Invalid name length in session request\n"));
140 name_extract(inbuf,4,name1);
141 name_extract(inbuf,4 + name_len(inbuf + 4),name2);
142 DEBUG(2,("netbios connect: name1=%s name2=%s\n",
145 fstrcpy(remote_machine,name2);
146 remote_machine[15] = 0;
147 trim_string(remote_machine," "," ");
148 strlower(remote_machine);
150 fstrcpy(local_machine,name1);
151 len = strlen(local_machine);
153 name_type = local_machine[15];
154 local_machine[15] = 0;
156 trim_string(local_machine," "," ");
157 strlower(local_machine);
159 if (name_type == 'R') {
160 /* We are being asked for a pathworks session ---
162 CVAL(outbuf, 0) = 0x83;
166 add_session_user(remote_machine);
168 reload_services(True);
172 claim_connection(NULL,"STATUS.",MAXSTATUS,True);
177 case 0x89: /* session keepalive request
178 (some old clients produce this?) */
179 CVAL(outbuf,0) = 0x85;
183 case 0x82: /* positive session response */
184 case 0x83: /* negative session response */
185 case 0x84: /* retarget session response */
186 DEBUG(0,("Unexpected session response\n"));
189 case 0x85: /* session keepalive */
194 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
195 msg_type, msg_flags));
201 /*******************************************************************
202 work out what error to give to a failed connection
203 ********************************************************************/
204 static int connection_error(char *inbuf,char *outbuf,int ecode)
206 if (ecode == ERRnoipc) {
207 return(ERROR(ERRDOS,ERRnoipc));
210 return(ERROR(ERRSRV,ecode));
215 /****************************************************************************
216 parse a share descriptor string
217 ****************************************************************************/
218 static void parse_connect(char *p,char *service,char *user,
219 char *password,int *pwlen,char *dev)
223 DEBUG(4,("parsing connect string %s\n",p));
225 p2 = strrchr(p,'\\');
229 fstrcpy(service,p2+1);
234 *pwlen = strlen(password);
241 p = strchr(service,'%');
252 /****************************************************************************
254 ****************************************************************************/
255 int reply_tcon(connection_struct *conn,
256 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
263 uint16 vuid = SVAL(inbuf,smb_uid);
267 *service = *user = *password = *dev = 0;
269 parse_connect(smb_buf(inbuf)+1,service,user,password,&pwlen,dev);
271 map_nt_and_unix_username(global_myworkgroup, user);
273 conn = make_connection(service,user,password,pwlen,dev,vuid,&ecode);
276 return(connection_error(inbuf,outbuf,ecode));
279 outsize = set_message(outbuf,2,0,True);
280 SSVAL(outbuf,smb_vwv0,max_recv);
281 SSVAL(outbuf,smb_vwv1,conn->cnum);
282 SSVAL(outbuf,smb_tid,conn->cnum);
284 DEBUG(3,("tcon service=%s user=%s cnum=%d\n",
285 service, user, conn->cnum));
291 /****************************************************************************
292 reply to a tcon and X
293 ****************************************************************************/
294 int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
301 uint16 vuid = SVAL(inbuf,smb_uid);
302 int passlen = SVAL(inbuf,smb_vwv3);
306 *service = *user = *password = *devicename = 0;
308 /* we might have to close an old one */
309 if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
310 close_cnum(conn,vuid);
313 if (passlen > MAX_PASS_LEN) {
314 overflow_attack(passlen);
317 memcpy(password,smb_buf(inbuf),passlen);
319 path = smb_buf(inbuf) + passlen;
322 if (strequal(password," "))
324 passlen = strlen(password);
327 fstrcpy(service,path+2);
328 p = strchr(service,'\\');
330 return(ERROR(ERRSRV,ERRinvnetname));
332 fstrcpy(service,p+1);
333 p = strchr(service,'%');
338 StrnCpy(devicename,path + strlen(path) + 1,6);
339 DEBUG(4,("Got device type %s\n",devicename));
341 map_nt_and_unix_username(global_myworkgroup, user);
343 conn = make_connection(service,user,password,passlen,devicename,vuid,&ecode);
346 return(connection_error(inbuf,outbuf,ecode));
348 if (Protocol < PROTOCOL_NT1) {
349 set_message(outbuf,2,strlen(devicename)+1,True);
350 pstrcpy(smb_buf(outbuf),devicename);
352 char *fsname = lp_fstype(SNUM(conn));
354 set_message(outbuf,3,3,True);
357 pstrcpy(p,devicename); p = skip_string(p,1); /* device name */
358 pstrcpy(p,fsname); p = skip_string(p,1); /* filesystem type e.g NTFS */
360 set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
362 /* what does setting this bit do? It is set by NT4 and
363 may affect the ability to autorun mounted cdroms */
364 SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS);
367 DEBUG(3,("tconX service=%s user=%s\n",
370 /* set the incoming and outgoing tid to the just created one */
371 SSVAL(inbuf,smb_tid,conn->cnum);
372 SSVAL(outbuf,smb_tid,conn->cnum);
374 return chain_reply(inbuf,outbuf,length,bufsize);
378 /****************************************************************************
379 reply to an unknown type
380 ****************************************************************************/
381 int reply_unknown(char *inbuf,char *outbuf)
384 type = CVAL(inbuf,smb_com);
386 DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
387 smb_fn_name(type), type, type));
389 return(ERROR(ERRSRV,ERRunknownsmb));
393 /****************************************************************************
395 ****************************************************************************/
396 int reply_ioctl(connection_struct *conn,
397 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
399 DEBUG(3,("ignoring ioctl\n"));
401 /* we just say it succeeds and hope its all OK.
402 some day it would be nice to interpret them individually */
403 return set_message(outbuf,1,0,True);
405 return(ERROR(ERRSRV,ERRnosupport));
409 /****************************************************************************
410 always return an error: it's just a matter of which one...
411 ****************************************************************************/
412 static int session_trust_account(connection_struct *conn, char *inbuf, char *outbuf, char *user,
413 char *smb_passwd, int smb_passlen,
414 char *smb_nt_passwd, int smb_nt_passlen)
416 struct smb_passwd *smb_trust_acct = NULL; /* check if trust account exists */
417 if (lp_security() == SEC_USER)
419 smb_trust_acct = getsmbpwnam(user);
423 DEBUG(0,("session_trust_account: Trust account %s only supported with security = user\n", user));
424 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
425 return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
428 if (smb_trust_acct == NULL)
430 /* lkclXXXX: workstation entry doesn't exist */
431 DEBUG(0,("session_trust_account: Trust account %s user doesn't exist\n",user));
432 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
433 return(ERROR(0, 0xc0000000|NT_STATUS_NO_SUCH_USER));
437 if ((smb_passlen != 24) || (smb_nt_passlen != 24))
439 DEBUG(0,("session_trust_account: Trust account %s - password length wrong.\n", user));
440 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
441 return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
444 if (!smb_password_ok(smb_trust_acct, NULL, NULL, NULL,
445 (unsigned char *)smb_passwd, smb_passlen,
446 (unsigned char *)smb_nt_passwd, smb_nt_passlen))
448 DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
449 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
450 return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
453 if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_DOMTRUST))
455 DEBUG(0,("session_trust_account: Domain trust account %s denied by server\n",user));
456 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
457 return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT));
460 if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_SVRTRUST))
462 DEBUG(0,("session_trust_account: Server trust account %s denied by server\n",user));
463 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
464 return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT));
467 if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_WSTRUST))
469 DEBUG(4,("session_trust_account: Wksta trust account %s denied by server\n", user));
470 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
471 return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT));
475 /* don't know what to do: indicate logon failure */
476 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
477 return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
480 /****************************************************************************
481 Check for a valid username and password in security=server mode.
482 ****************************************************************************/
484 static BOOL check_server_security(char *orig_user, char *domain,
485 char *smb_apasswd, int smb_apasslen,
486 char *smb_ntpasswd, int smb_ntpasslen)
488 if(lp_security() != SEC_SERVER)
491 return server_validate(orig_user, domain,
492 smb_apasswd, smb_apasslen,
493 smb_ntpasswd, smb_ntpasslen);
496 /****************************************************************************
497 Check for a valid username and password in security=domain mode.
498 ****************************************************************************/
500 static BOOL check_domain_security(char *orig_user, char *domain,
501 char *smb_apasswd, int smb_apasslen,
502 char *smb_ntpasswd, int smb_ntpasslen)
504 if(lp_security() != SEC_DOMAIN)
507 return domain_client_validate(orig_user, domain,
508 smb_apasswd, smb_apasslen,
509 smb_ntpasswd, smb_ntpasslen);
512 /****************************************************************************
513 reply to a session setup command
514 ****************************************************************************/
516 int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
519 uchar user_sess_key[16];
523 int smb_apasslen = 0;
525 int smb_ntpasslen = 0;
526 pstring smb_ntpasswd;
527 BOOL valid_nt_password = False;
531 static BOOL done_sesssetup = False;
532 BOOL doencrypt = SMBENCRYPT();
538 smb_bufsize = SVAL(inbuf,smb_vwv2);
540 if (Protocol < PROTOCOL_NT1)
542 smb_apasslen = SVAL(inbuf,smb_vwv7);
543 if (smb_apasslen > MAX_PASS_LEN)
545 overflow_attack(smb_apasslen);
548 memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
549 smb_apasswd[smb_apasslen] = 0;
550 pstrcpy(user,smb_buf(inbuf)+smb_apasslen);
552 if (!doencrypt && (lp_security() != SEC_SERVER)) {
553 smb_apasslen = strlen(smb_apasswd);
556 if (lp_server_ntlmv2() == True)
558 DEBUG(1,("NTLMv2-only accepted with NT LANMAN 1.0 and above.\n\
559 user %s attempted down-level SMB connection\n", user));
560 return(ERROR(ERRSRV,ERRbadpw));
565 uint16 passlen1 = SVAL(inbuf,smb_vwv7);
566 uint16 passlen2 = SVAL(inbuf,smb_vwv8);
567 enum remote_arch_types ra_type = get_remote_arch();
568 char *p = smb_buf(inbuf);
570 global_client_caps = IVAL(inbuf,smb_vwv11);
572 /* client_caps is used as final determination if client is NT or Win95.
573 This is needed to return the correct error codes in some
577 if(ra_type == RA_WINNT || ra_type == RA_WIN95)
579 if(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))
580 set_remote_arch( RA_WINNT);
582 set_remote_arch( RA_WIN95);
585 if (passlen1 != 24 && passlen2 <= 24)
588 if (passlen1 > MAX_PASS_LEN) {
589 overflow_attack(passlen1);
592 passlen1 = MIN(passlen1, MAX_PASS_LEN);
593 passlen2 = MIN(passlen2, MAX_PASS_LEN);
596 /* both Win95 and WinNT stuff up the password lengths for
597 non-encrypting systems. Uggh.
599 if passlen1==24 its a win95 system, and its setting the
600 password length incorrectly. Luckily it still works with the
601 default code because Win95 will null terminate the password
604 if passlen1>0 and passlen2>0 then maybe its a NT box and its
605 setting passlen2 to some random value which really stuffs
606 things up. we need to fix that one.
608 LKCLXXXX: the random value can be random 16 bit. old test
609 used to have ... && passlen <= 24) which of course fails
613 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 1)
617 if (doencrypt || ((lp_security() == SEC_SERVER) || (lp_security() == SEC_DOMAIN))) {
618 /* Save the lanman2 password and the NT md4 password. */
619 smb_apasslen = passlen1;
620 memcpy(smb_apasswd,p,smb_apasslen);
621 smb_apasswd[smb_apasslen] = 0;
622 smb_ntpasslen = passlen2;
623 memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen);
624 smb_ntpasswd[smb_ntpasslen] = 0;
626 /* we use the first password that they gave */
627 smb_apasslen = passlen1;
628 StrnCpy(smb_apasswd,p,smb_apasslen);
630 /* trim the password */
631 smb_apasslen = strlen(smb_apasswd);
633 /* wfwg sometimes uses a space instead of a null */
634 if (strequal(smb_apasswd," ")) {
640 if (passlen2 == 0 && smb_apasslen == 0 && ra_type == RA_WIN95)
642 /* work-around for win95 NULL sessions, where NULL password is
643 actually put in the data stream before the domain name etc */
648 p += passlen1 + passlen2;
651 fstrcpy(user,p); p = skip_string(p,1);
654 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n",
655 domain, skip_string(p,1), skip_string(p,2)));
658 DEBUG(3,("sesssetupX:name=[%s]\n",user));
660 /* If name ends in $ then I think it's asking about whether a */
661 /* computer with that name (minus the $) has access. For now */
662 /* say yes to everything ending in $. */
663 if ((user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24))
665 return session_trust_account(conn, inbuf, outbuf, user,
666 smb_apasswd, smb_apasslen,
667 smb_ntpasswd, smb_ntpasslen);
670 /* If no username is sent use the guest account */
673 pstrcpy(user,lp_guestaccount(-1));
674 /* If no user and no password then set guest flag. */
675 if( *smb_apasswd == 0)
681 * In share level security, only overwrite sesssetup_use if
682 * it's a non null-session share. Helps keep %U and %G
686 if((lp_security() != SEC_SHARE) || (*user && !guest))
687 pstrcpy(sesssetup_user,user);
688 reload_services(True);
691 * Save the username before mapping. We will use
692 * the original username sent to us for security=server
693 * and security=domain checking.
696 pstrcpy( orig_user, user);
698 map_nt_and_unix_username(domain, user);
700 add_session_user(user);
703 * Check if the given username was the guest user with no password.
706 if(!guest && strequal(user,lp_guestaccount(-1)) && (*smb_apasswd == 0))
710 * Check with orig_user for security=server and
715 !check_server_security(orig_user, domain,
716 smb_apasswd, smb_apasslen,
717 smb_ntpasswd, smb_ntpasslen) &&
718 !check_domain_security(orig_user, domain,
719 smb_apasswd, smb_apasslen,
720 smb_ntpasswd, smb_ntpasslen) &&
721 !check_hosts_equiv(user)
726 * If we get here then the user wasn't guest and the remote
727 * authentication methods failed. Check the authentication
728 * methods on this local server.
730 * If an NT password was supplied try and validate with that
731 * first. This is superior as the passwords are mixed case
732 * 128 length unicode.
737 if(!password_ok(user, smb_ntpasswd,smb_ntpasslen,NULL,user_sess_key))
738 DEBUG(0,("NT Password did not match ! Defaulting to Lanman\n"));
740 valid_nt_password = True;
743 if (!valid_nt_password && !password_ok(user, smb_apasswd,smb_apasslen,NULL,user_sess_key))
745 if (lp_security() >= SEC_USER)
747 if (lp_map_to_guest() == NEVER_MAP_TO_GUEST)
748 return(ERROR(ERRSRV,ERRbadpw));
750 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER)
752 if (Get_Pwnam(user,True))
753 return(ERROR(ERRSRV,ERRbadpw));
757 * ..else if lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
758 * Then always map to guest account - as done below.
762 if (*smb_apasswd || !Get_Pwnam(user,True))
763 pstrcpy(user,lp_guestaccount(-1));
764 DEBUG(3,("Registered username %s for guest access\n",user));
769 if (!Get_Pwnam(user,True)) {
770 DEBUG(3,("No such user %s - using guest account\n",user));
771 pstrcpy(user,lp_guestaccount(-1));
775 if (!strequal(user,lp_guestaccount(-1)) &&
776 lp_servicenumber(user) < 0)
778 int homes = lp_servicenumber(HOMES_NAME);
779 char *home = get_home_dir(user);
780 if (homes >= 0 && home)
783 fstrcpy(home_dir, home);
784 lp_add_home(user,homes,home_dir);
788 /* it's ok - setup a reply */
789 if (Protocol < PROTOCOL_NT1) {
790 set_message(outbuf,3,0,True);
793 set_message(outbuf,3,3,True);
795 pstrcpy(p,"Unix"); p = skip_string(p,1);
796 pstrcpy(p,"Samba "); pstrcat(p,VERSION); p = skip_string(p,1);
797 pstrcpy(p,global_myworkgroup); p = skip_string(p,1);
798 set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
799 /* perhaps grab OS version here?? */
802 /* Set the correct uid in the outgoing and incoming packets
803 We will use this on future requests to determine which
804 user we should become.
807 const struct passwd *pw = Get_Pwnam(user,False);
809 DEBUG(1,("Username %s is invalid on this system\n",user));
810 return(ERROR(ERRSRV,ERRbadpw));
817 SSVAL(outbuf,smb_vwv2,1);
819 /* register the name and uid as being validated, so further connections
820 to a uid can get through without a password, on the same VC */
821 sess_vuid = register_vuid(uid,gid,user,sesssetup_user,guest,user_sess_key);
823 SSVAL(outbuf,smb_uid,sess_vuid);
824 SSVAL(inbuf,smb_uid,sess_vuid);
827 max_send = MIN(max_send,smb_bufsize);
829 DEBUG(6,("Client requested max send size of %d\n", max_send));
831 done_sesssetup = True;
833 return chain_reply(inbuf,outbuf,length,bufsize);
837 /****************************************************************************
839 ****************************************************************************/
840 int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
846 BOOL bad_path = False;
849 pstrcpy(name,smb_buf(inbuf) + 1);
850 if (!unix_dfs_convert(name,conn,0,&bad_path,&st))
852 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
853 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
856 mode = SVAL(inbuf,smb_vwv0);
858 if (check_name(name,conn)) {
860 ok = S_ISDIR(st.st_mode);
862 ok = dos_directory_exist(name,NULL);
867 /* We special case this - as when a Windows machine
868 is parsing a path is steps through the components
869 one at a time - if a component fails it expects
870 ERRbadpath, not ERRbadfile.
874 unix_ERR_class = ERRDOS;
875 unix_ERR_code = ERRbadpath;
879 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
880 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
881 (get_remote_arch() == RA_WINNT))
883 unix_ERR_class = ERRDOS;
884 unix_ERR_code = ERRbaddirectory;
888 return(UNIXERROR(ERRDOS,ERRbadpath));
891 outsize = set_message(outbuf,0,0,True);
893 DEBUG(3,("chkpth %s mode=%d\n", name, mode));
899 /****************************************************************************
901 ****************************************************************************/
902 int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
906 SMB_STRUCT_STAT sbuf;
911 BOOL bad_path = False;
913 pstrcpy(fname,smb_buf(inbuf) + 1);
915 /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
916 under WfWg - weird! */
919 mode = aHIDDEN | aDIR;
920 if (!CAN_WRITE(conn)) mode |= aRONLY;
927 if (!unix_dfs_convert(fname,conn,0,&bad_path,&sbuf))
929 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
930 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
932 if (check_name(fname,conn))
934 if (VALID_STAT(sbuf) || conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf) == 0)
936 mode = dos_mode(conn,fname,&sbuf);
938 mtime = sbuf.st_mtime;
944 DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
950 if((errno == ENOENT) && bad_path)
952 unix_ERR_class = ERRDOS;
953 unix_ERR_code = ERRbadpath;
956 return(UNIXERROR(ERRDOS,ERRbadfile));
959 outsize = set_message(outbuf,10,0,True);
961 SSVAL(outbuf,smb_vwv0,mode);
962 if(lp_dos_filetime_resolution(SNUM(conn)) )
963 put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
965 put_dos_date3(outbuf,smb_vwv1,mtime);
966 SIVAL(outbuf,smb_vwv3,(uint32)size);
968 if (Protocol >= PROTOCOL_NT1) {
969 char *p = strrchr(fname,'/');
970 uint16 flg2 = SVAL(outbuf,smb_flg2);
972 if (!is_8_3(fname, True))
973 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
976 DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
982 /****************************************************************************
984 ****************************************************************************/
985 int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
993 BOOL bad_path = False;
995 pstrcpy(fname,smb_buf(inbuf) + 1);
996 if (!unix_dfs_convert(fname,conn,0,&bad_path,&st))
998 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
999 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
1002 mode = SVAL(inbuf,smb_vwv0);
1003 mtime = make_unix_date3(inbuf+smb_vwv1);
1005 if (VALID_STAT_OF_DIR(st) || dos_directory_exist(fname,NULL))
1007 if (check_name(fname,conn))
1008 ok = (file_chmod(conn,fname,mode,NULL) == 0);
1010 ok = set_filetime(conn,fname,mtime);
1014 if((errno == ENOENT) && bad_path)
1016 unix_ERR_class = ERRDOS;
1017 unix_ERR_code = ERRbadpath;
1020 return(UNIXERROR(ERRDOS,ERRnoaccess));
1023 outsize = set_message(outbuf,0,0,True);
1025 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
1031 /****************************************************************************
1033 ****************************************************************************/
1034 int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1037 SMB_BIG_UINT dfree,dsize,bsize;
1039 conn->vfs_ops.disk_free(".",&bsize,&dfree,&dsize);
1041 outsize = set_message(outbuf,5,0,True);
1043 SSVAL(outbuf,smb_vwv0,dsize);
1044 SSVAL(outbuf,smb_vwv1,bsize/512);
1045 SSVAL(outbuf,smb_vwv2,512);
1046 SSVAL(outbuf,smb_vwv3,dfree);
1048 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree));
1054 /****************************************************************************
1056 Can be called from SMBsearch, SMBffirst or SMBfunique.
1057 ****************************************************************************/
1058 int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1069 BOOL finished = False;
1078 BOOL check_descend = False;
1079 BOOL expect_close = False;
1080 BOOL can_open = True;
1081 BOOL bad_path = False;
1083 *mask = *directory = *fname = 0;
1085 /* If we were called as SMBffirst then we must expect close. */
1086 if(CVAL(inbuf,smb_com) == SMBffirst)
1087 expect_close = True;
1089 outsize = set_message(outbuf,1,3,True);
1090 maxentries = SVAL(inbuf,smb_vwv0);
1091 dirtype = SVAL(inbuf,smb_vwv1);
1092 path = smb_buf(inbuf) + 1;
1093 status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
1096 /* dirtype &= ~aDIR; */
1098 DEBUG(5,("path=%s status_len=%d\n",path,status_len));
1101 if (status_len == 0)
1105 pstrcpy(directory,smb_buf(inbuf)+1);
1106 pstrcpy(dir2,smb_buf(inbuf)+1);
1107 if (!unix_dfs_convert(directory,conn,0,&bad_path,NULL))
1109 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
1110 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
1114 if (!check_name(directory,conn))
1117 p = strrchr(dir2,'/');
1129 p = strrchr(directory,'/');
1135 if (strlen(directory) == 0)
1136 pstrcpy(directory,"./");
1138 CVAL(status,0) = dirtype;
1142 memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
1143 memcpy(mask,status+1,11);
1145 dirtype = CVAL(status,0) & 0x1F;
1146 conn->dirptr = dptr_fetch(status+12,&dptr_num);
1149 string_set(&conn->dirpath,dptr_path(dptr_num));
1150 if (!case_sensitive)
1154 /* turn strings of spaces into a . */
1156 trim_string(mask,NULL," ");
1157 if ((p = strrchr(mask,' ')))
1162 trim_string(mask,NULL," ");
1168 /* Convert the formatted mask. (This code lives in trans2.c) */
1176 if((skip = skip_multibyte_char( *p )) != 0 )
1182 if (*p != '?' && *p != '*' && !isdoschar(*p))
1184 DEBUG(5,("Invalid char [%c] in search mask?\n",*p));
1192 if (!strchr(mask,'.') && strlen(mask)>8)
1195 fstrcpy(tmp,&mask[8]);
1201 DEBUG(5,("mask=%s directory=%s\n",mask,directory));
1205 p = smb_buf(outbuf) + 3;
1209 if (status_len == 0)
1211 dptr_num = dptr_create(conn,directory,expect_close,SVAL(inbuf,smb_pid));
1216 if((errno == ENOENT) && bad_path)
1218 unix_ERR_class = ERRDOS;
1219 unix_ERR_code = ERRbadpath;
1221 return (UNIXERROR(ERRDOS,ERRnofids));
1223 return(ERROR(ERRDOS,ERRnofids));
1227 DEBUG(4,("dptr_num is %d\n",dptr_num));
1231 if ((dirtype&0x1F) == aVOLID)
1233 memcpy(p,status,21);
1234 make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
1235 dptr_fill(p+12,dptr_num);
1236 if (dptr_zero(p+12) && (status_len==0))
1240 p += DIR_STRUCT_SIZE;
1244 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
1245 conn->dirpath,lp_dontdescend(SNUM(conn))));
1246 if (in_list(conn->dirpath,
1247 lp_dontdescend(SNUM(conn)),True))
1248 check_descend = True;
1250 for (i=numentries;(i<maxentries) && !finished;i++)
1253 !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
1256 memcpy(p,status,21);
1257 make_dir_struct(p,mask,fname,size,mode,date);
1258 dptr_fill(p+12,dptr_num);
1261 p += DIR_STRUCT_SIZE;
1270 if (numentries == 0 || !ok)
1272 CVAL(outbuf,smb_rcls) = ERRDOS;
1273 SSVAL(outbuf,smb_err,ERRnofiles);
1276 /* If we were called as SMBffirst with smb_search_id == NULL
1277 and no entries were found then return error and close dirptr
1280 if(ok && expect_close && numentries == 0 && status_len == 0)
1282 CVAL(outbuf,smb_rcls) = ERRDOS;
1283 SSVAL(outbuf,smb_err,ERRnofiles);
1284 /* Also close the dptr - we know it's gone */
1285 dptr_close(dptr_num);
1288 /* If we were called as SMBfunique, then we can close the dirptr now ! */
1289 if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique)
1290 dptr_close(dptr_num);
1292 SSVAL(outbuf,smb_vwv0,numentries);
1293 SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
1294 CVAL(smb_buf(outbuf),0) = 5;
1295 SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
1297 if (Protocol >= PROTOCOL_NT1) {
1298 uint16 flg2 = SVAL(outbuf,smb_flg2);
1299 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
1302 outsize += DIR_STRUCT_SIZE*numentries;
1303 smb_setlen(outbuf,outsize - 4);
1305 if ((! *directory) && dptr_path(dptr_num))
1306 slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1308 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%d of %d\n",
1309 smb_fn_name(CVAL(inbuf,smb_com)),
1310 mask, directory, dirtype, numentries, maxentries ) );
1316 /****************************************************************************
1317 reply to a fclose (stop directory search)
1318 ****************************************************************************/
1319 int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1327 outsize = set_message(outbuf,1,0,True);
1328 path = smb_buf(inbuf) + 1;
1329 status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
1332 if (status_len == 0)
1333 return(ERROR(ERRSRV,ERRsrverror));
1335 memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
1337 if(dptr_fetch(status+12,&dptr_num)) {
1338 /* Close the dptr - we know it's gone */
1339 dptr_close(dptr_num);
1342 SSVAL(outbuf,smb_vwv0,0);
1344 DEBUG(3,("search close\n"));
1350 /****************************************************************************
1352 ****************************************************************************/
1354 int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1364 SMB_STRUCT_STAT sbuf;
1365 BOOL bad_path = False;
1367 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1369 share_mode = SVAL(inbuf,smb_vwv0);
1371 pstrcpy(fname,smb_buf(inbuf)+1);
1372 if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
1374 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
1375 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
1380 return(ERROR(ERRSRV,ERRnofids));
1382 if (!check_name(fname,conn))
1384 if((errno == ENOENT) && bad_path)
1386 unix_ERR_class = ERRDOS;
1387 unix_ERR_code = ERRbadpath;
1390 return(UNIXERROR(ERRDOS,ERRnoaccess));
1393 unixmode = unix_mode(conn,aARCH);
1395 open_file_shared(fsp, conn, fname, share_mode,
1396 (FILE_FAIL_IF_NOT_EXIST | FILE_EXISTS_OPEN),
1397 unixmode, oplock_request, &rmode, NULL);
1401 if((errno == ENOENT) && bad_path)
1403 unix_ERR_class = ERRDOS;
1404 unix_ERR_code = ERRbadpath;
1407 return(UNIXERROR(ERRDOS,ERRnoaccess));
1410 if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
1411 close_file(fsp,False);
1412 return(ERROR(ERRDOS,ERRnoaccess));
1415 size = sbuf.st_size;
1416 fmode = dos_mode(conn,fname,&sbuf);
1417 mtime = sbuf.st_mtime;
1420 DEBUG(3,("attempt to open a directory %s\n",fname));
1421 close_file(fsp,False);
1422 return(ERROR(ERRDOS,ERRnoaccess));
1425 outsize = set_message(outbuf,7,0,True);
1426 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1427 SSVAL(outbuf,smb_vwv1,fmode);
1428 if(lp_dos_filetime_resolution(SNUM(conn)) )
1429 put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
1431 put_dos_date3(outbuf,smb_vwv2,mtime);
1432 SIVAL(outbuf,smb_vwv4,(uint32)size);
1433 SSVAL(outbuf,smb_vwv6,rmode);
1435 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1436 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1439 if(fsp->granted_oplock)
1440 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1445 /****************************************************************************
1446 reply to an open and X
1447 ****************************************************************************/
1448 int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1451 int smb_mode = SVAL(inbuf,smb_vwv3);
1452 int smb_attr = SVAL(inbuf,smb_vwv5);
1453 /* Breakout the oplock request bits so we can set the
1454 reply bits separately. */
1455 BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
1456 BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1457 BOOL oplock_request = ex_oplock_request | core_oplock_request;
1459 int open_flags = SVAL(inbuf,smb_vwv2);
1460 int smb_sattr = SVAL(inbuf,smb_vwv4);
1461 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
1463 int smb_ofun = SVAL(inbuf,smb_vwv8);
1466 int fmode=0,mtime=0,rmode=0;
1467 SMB_STRUCT_STAT sbuf;
1469 BOOL bad_path = False;
1472 /* If it's an IPC, pass off the pipe handler. */
1473 if (IS_IPC(conn) && lp_nt_pipe_support() && lp_security() != SEC_SHARE)
1475 return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
1478 /* XXXX we need to handle passed times, sattr and flags */
1480 pstrcpy(fname,smb_buf(inbuf));
1481 if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
1483 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
1484 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
1489 return(ERROR(ERRSRV,ERRnofids));
1491 if (!check_name(fname,conn))
1493 if((errno == ENOENT) && bad_path)
1495 unix_ERR_class = ERRDOS;
1496 unix_ERR_code = ERRbadpath;
1499 return(UNIXERROR(ERRDOS,ERRnoaccess));
1502 unixmode = unix_mode(conn,smb_attr | aARCH);
1504 open_file_shared(fsp, conn, fname, smb_mode, smb_ofun, unixmode,
1505 oplock_request, &rmode, &smb_action);
1509 if((errno == ENOENT) && bad_path)
1511 unix_ERR_class = ERRDOS;
1512 unix_ERR_code = ERRbadpath;
1515 return(UNIXERROR(ERRDOS,ERRnoaccess));
1518 if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
1519 close_file(fsp,False);
1520 return(ERROR(ERRDOS,ERRnoaccess));
1523 size = sbuf.st_size;
1524 fmode = dos_mode(conn,fname,&sbuf);
1525 mtime = sbuf.st_mtime;
1527 close_file(fsp,False);
1528 return(ERROR(ERRDOS,ERRnoaccess));
1531 /* If the caller set the extended oplock request bit
1532 and we granted one (by whatever means) - set the
1533 correct bit for extended oplock reply.
1536 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1537 smb_action |= EXTENDED_OPLOCK_GRANTED;
1540 if(ex_oplock_request && fsp->granted_oplock) {
1541 smb_action |= EXTENDED_OPLOCK_GRANTED;
1544 /* If the caller set the core oplock request bit
1545 and we granted one (by whatever means) - set the
1546 correct bit for core oplock reply.
1549 if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
1550 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1553 if(core_oplock_request && fsp->granted_oplock) {
1554 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1557 set_message(outbuf,15,0,True);
1558 SSVAL(outbuf,smb_vwv2,fsp->fnum);
1559 SSVAL(outbuf,smb_vwv3,fmode);
1560 if(lp_dos_filetime_resolution(SNUM(conn)) )
1561 put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
1563 put_dos_date3(outbuf,smb_vwv4,mtime);
1564 SIVAL(outbuf,smb_vwv6,(uint32)size);
1565 SSVAL(outbuf,smb_vwv8,rmode);
1566 SSVAL(outbuf,smb_vwv11,smb_action);
1568 return chain_reply(inbuf,outbuf,length,bufsize);
1572 /****************************************************************************
1573 reply to a SMBulogoffX
1574 ****************************************************************************/
1575 int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
1577 uint16 vuid = SVAL(inbuf,smb_uid);
1578 user_struct *vuser = get_valid_user_struct(vuid);
1581 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
1584 /* in user level security we are supposed to close any files
1585 open by this user */
1586 if ((vuser != 0) && (lp_security() != SEC_SHARE)) {
1587 file_close_user(vuid);
1590 invalidate_vuid(vuid);
1592 set_message(outbuf,2,0,True);
1594 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
1596 return chain_reply(inbuf,outbuf,length,bufsize);
1600 /****************************************************************************
1601 reply to a mknew or a create
1602 ****************************************************************************/
1603 int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1611 BOOL bad_path = False;
1613 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1615 com = SVAL(inbuf,smb_com);
1617 createmode = SVAL(inbuf,smb_vwv0);
1618 pstrcpy(fname,smb_buf(inbuf)+1);
1619 if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
1621 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
1622 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
1625 if (createmode & aVOLID)
1627 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
1630 unixmode = unix_mode(conn,createmode);
1634 return(ERROR(ERRSRV,ERRnofids));
1636 if (!check_name(fname,conn))
1638 if((errno == ENOENT) && bad_path)
1640 unix_ERR_class = ERRDOS;
1641 unix_ERR_code = ERRbadpath;
1644 return(UNIXERROR(ERRDOS,ERRnoaccess));
1649 /* We should fail if file exists. */
1654 /* SMBcreate - Create if file doesn't exist, truncate if it does. */
1658 /* Open file in dos compatibility share mode. */
1659 open_file_shared(fsp, conn, fname,
1660 SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1661 ofun, unixmode, oplock_request, NULL, NULL);
1665 if((errno == ENOENT) && bad_path)
1667 unix_ERR_class = ERRDOS;
1668 unix_ERR_code = ERRbadpath;
1671 return(UNIXERROR(ERRDOS,ERRnoaccess));
1674 outsize = set_message(outbuf,1,0,True);
1675 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1677 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1678 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1681 if(fsp->granted_oplock)
1682 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1684 DEBUG( 2, ( "new file %s\n", fname ) );
1685 DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n",
1686 fname, fsp->fd_ptr->fd, createmode, (int)unixmode ) );
1692 /****************************************************************************
1693 reply to a create temporary file
1694 ****************************************************************************/
1695 int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1702 BOOL bad_path = False;
1704 int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
1706 createmode = SVAL(inbuf,smb_vwv0);
1707 pstrcpy(fname,smb_buf(inbuf)+1);
1708 pstrcat(fname,"/TMXXXXXX");
1709 if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
1711 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
1712 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
1715 unixmode = unix_mode(conn,createmode);
1719 return(ERROR(ERRSRV,ERRnofids));
1721 if (!check_name(fname,conn))
1723 if((errno == ENOENT) && bad_path)
1725 unix_ERR_class = ERRDOS;
1726 unix_ERR_code = ERRbadpath;
1729 return(UNIXERROR(ERRDOS,ERRnoaccess));
1732 pstrcpy(fname2,(char *)mktemp(fname));
1734 /* Open file in dos compatibility share mode. */
1735 /* We should fail if file exists. */
1736 open_file_shared(fsp,conn,fname2,
1737 SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
1738 (FILE_CREATE_IF_NOT_EXIST | FILE_EXISTS_FAIL),
1739 unixmode, oplock_request, NULL, NULL);
1743 if((errno == ENOENT) && bad_path)
1745 unix_ERR_class = ERRDOS;
1746 unix_ERR_code = ERRbadpath;
1749 return(UNIXERROR(ERRDOS,ERRnoaccess));
1752 outsize = set_message(outbuf,1,2 + strlen(fname2),True);
1753 SSVAL(outbuf,smb_vwv0,fsp->fnum);
1754 CVAL(smb_buf(outbuf),0) = 4;
1755 pstrcpy(smb_buf(outbuf) + 1,fname2);
1757 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1758 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1761 if(fsp->granted_oplock)
1762 CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
1764 DEBUG( 2, ( "created temp file %s\n", fname2 ) );
1765 DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
1766 fname2, fsp->fd_ptr->fd, createmode, (int)unixmode ) );
1772 /*******************************************************************
1773 check if a user is allowed to delete a file
1774 ********************************************************************/
1775 static BOOL can_delete(char *fname,connection_struct *conn, int dirtype)
1777 SMB_STRUCT_STAT sbuf;
1780 if (!CAN_WRITE(conn)) return(False);
1782 if (conn->vfs_ops.lstat(fname,&sbuf) != 0) return(False);
1783 fmode = dos_mode(conn,fname,&sbuf);
1784 if (fmode & aDIR) return(False);
1785 if (!lp_delete_readonly(SNUM(conn))) {
1786 if (fmode & aRONLY) return(False);
1788 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
1790 if (!check_file_sharing(conn,fname,False)) return(False);
1794 /****************************************************************************
1796 ****************************************************************************/
1797 int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
1806 int error = ERRnoaccess;
1809 BOOL bad_path = False;
1811 *directory = *mask = 0;
1813 dirtype = SVAL(inbuf,smb_vwv0);
1815 pstrcpy(name,smb_buf(inbuf) + 1);
1817 DEBUG(3,("reply_unlink : %s\n",name));
1819 if (!unix_dfs_convert(name,conn,0,&bad_path,NULL))
1821 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
1822 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
1825 p = strrchr(name,'/');
1827 pstrcpy(directory,"./");
1831 pstrcpy(directory,name);
1835 if (is_mangled(mask))
1836 check_mangled_cache( mask );
1838 has_wild = strchr(mask,'*') || strchr(mask,'?');
1841 pstrcat(directory,"/");
1842 pstrcat(directory,mask);
1843 if (can_delete(directory,conn,dirtype) && !conn->vfs_ops.unlink(directory))
1846 exists = vfs_file_exist(conn,dos_to_unix(directory,False),NULL);
1848 void *dirptr = NULL;
1851 if (check_name(directory,conn))
1852 dirptr = OpenDir(conn, directory, True);
1854 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
1855 the pattern matches against the long name, otherwise the short name
1856 We don't implement this yet XXXX
1863 if (strequal(mask,"????????.???"))
1866 while ((dname = ReadDirName(dirptr)))
1869 pstrcpy(fname,dname);
1871 if(!mask_match(fname, mask, case_sensitive, False)) continue;
1873 error = ERRnoaccess;
1874 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
1875 if (!can_delete(fname,conn,dirtype)) continue;
1876 if (!conn->vfs_ops.unlink(fname)) count++;
1877 DEBUG(3,("reply_unlink : doing unlink on %s\n",fname));
1885 return(ERROR(ERRDOS,error));
1888 if((errno == ENOENT) && bad_path)
1890 unix_ERR_class = ERRDOS;
1891 unix_ERR_code = ERRbadpath;
1893 return(UNIXERROR(ERRDOS,error));
1897 outsize = set_message(outbuf,0,0,True);
1903 /****************************************************************************
1904 reply to a readbraw (core+ protocol)
1905 ****************************************************************************/
1906 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
1908 size_t maxcount,mincount;
1911 char *header = outbuf;
1916 * Special check if an oplock break has been issued
1917 * and the readraw request croses on the wire, we must
1918 * return a zero length response here.
1921 if(global_oplock_break)
1923 _smb_setlen(header,0);
1924 transfer_file(0,Client,(SMB_OFF_T)0,header,4,0);
1925 DEBUG(5,("readbraw - oplock break finished\n"));
1929 fsp = file_fsp(inbuf,smb_vwv0);
1931 startpos = IVAL(inbuf,smb_vwv1);
1932 #ifdef LARGE_SMB_OFF_T
1933 if(CVAL(inbuf,smb_wct) == 10) {
1935 * This is a large offset (64 bit) read.
1937 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
1939 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n",
1940 (double)startpos ));
1941 _smb_setlen(header,0);
1942 transfer_file(0,Client,(SMB_OFF_T)0,header,4,0);
1946 #endif /* LARGE_SMB_OFF_T */
1947 maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
1948 mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
1950 /* ensure we don't overrun the packet size */
1951 maxcount = MIN(65535,maxcount);
1952 maxcount = MAX(mincount,maxcount);
1954 if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
1955 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",fsp->fnum));
1956 _smb_setlen(header,0);
1957 transfer_file(0,Client,(SMB_OFF_T)0,header,4,0);
1961 if (!is_locked(fsp,conn,maxcount,startpos, F_RDLCK))
1963 SMB_OFF_T size = fsp->size;
1964 SMB_OFF_T sizeneeded = startpos + maxcount;
1966 if (size < sizeneeded)
1969 if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&st) == 0)
1971 if (!fsp->can_write)
1975 nread = MIN(maxcount,(size - startpos));
1978 if (nread < mincount)
1981 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n",
1982 fsp->fnum, (double)startpos,
1983 maxcount, mincount, nread ) );
1987 BOOL seek_fail = False;
1989 _smb_setlen(header,nread);
1991 #if USE_READ_PREDICTION
1992 if (!fsp->can_write)
1993 predict = read_predict(fsp, fsp->fd_ptr->fd,startpos,header+4,NULL,nread);
1994 #endif /* USE_READ_PREDICTION */
1996 if ((nread-predict) > 0) {
1997 if(conn->vfs_ops.seek(fsp,startpos + predict) == -1) {
1998 DEBUG(0,("reply_readbraw: ERROR: seek_file failed.\n"));
2005 ret = (ssize_t)vfs_transfer_file(-1, fsp->fd_ptr->fd, Client, NULL,
2006 (SMB_OFF_T)(nread-predict),header,4+predict,
2011 DEBUG(0,("ERROR: file read failure on %s at %d for %d bytes (%d)\n",
2012 fsp->fsp_name,startpos,nread,ret));
2014 #else /* UNSAFE_READRAW */
2015 ret = read_file(fsp,header+4,startpos,nread);
2016 if (ret < mincount) ret = 0;
2018 _smb_setlen(header,ret);
2019 transfer_file(0,Client,0,header,4+ret,0);
2020 #endif /* UNSAFE_READRAW */
2022 DEBUG(5,("readbraw finished\n"));
2027 /****************************************************************************
2028 reply to a lockread (core+ protocol)
2029 ****************************************************************************/
2030 int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
2039 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2041 CHECK_FSP(fsp,conn);
2045 numtoread = SVAL(inbuf,smb_vwv1);
2046 startpos = IVAL(inbuf,smb_vwv2);
2048 outsize = set_message(outbuf,5,3,True);
2049 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
2050 data = smb_buf(outbuf) + 3;
2052 if(!do_lock( fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode)) {
2053 if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) {
2055 * A blocking lock was requested. Package up
2056 * this smb into a queued request and push it
2057 * onto the blocking lock queue.
2059 if(push_blocking_lock_request(inbuf, length, -1, 0))
2062 return (ERROR(eclass,ecode));
2065 nread = read_file(fsp,data,startpos,numtoread);
2068 return(UNIXERROR(ERRDOS,ERRnoaccess));
2071 SSVAL(outbuf,smb_vwv0,nread);
2072 SSVAL(outbuf,smb_vwv5,nread+3);
2073 SSVAL(smb_buf(outbuf),1,nread);
2075 DEBUG( 3, ( "lockread fnum=%d num=%d nread=%d\n",
2076 fsp->fnum, numtoread, nread ) );
2082 /****************************************************************************
2084 ****************************************************************************/
2085 int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2092 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2094 CHECK_FSP(fsp,conn);
2098 numtoread = SVAL(inbuf,smb_vwv1);
2099 startpos = IVAL(inbuf,smb_vwv2);
2101 outsize = set_message(outbuf,5,3,True);
2102 numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
2103 data = smb_buf(outbuf) + 3;
2105 if (is_locked(fsp,conn,numtoread,startpos, F_RDLCK))
2106 return(ERROR(ERRDOS,ERRlock));
2108 if (numtoread > 0) {
2109 nread = read_file(fsp,data,startpos,numtoread);
2113 return(UNIXERROR(ERRDOS,ERRnoaccess));
2116 SSVAL(outbuf,smb_vwv0,nread);
2117 SSVAL(outbuf,smb_vwv5,nread+3);
2118 CVAL(smb_buf(outbuf),0) = 1;
2119 SSVAL(smb_buf(outbuf),1,nread);
2121 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
2122 fsp->fnum, numtoread, nread ) );
2128 /****************************************************************************
2129 reply to a read and X
2130 ****************************************************************************/
2131 int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2133 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2134 SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3);
2135 size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
2136 size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
2140 /* If it's an IPC, pass off the pipe handler. */
2142 return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
2144 CHECK_FSP(fsp,conn);
2148 set_message(outbuf,12,0,True);
2149 data = smb_buf(outbuf);
2151 #ifdef LARGE_SMB_OFF_T
2152 if(CVAL(inbuf,smb_wct) == 12) {
2154 * This is a large offset (64 bit) read.
2156 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
2158 #endif /* LARGE_SMB_OFF_T */
2160 if (is_locked(fsp,conn,smb_maxcnt,startpos, F_RDLCK))
2161 return(ERROR(ERRDOS,ERRlock));
2162 nread = read_file(fsp,data,startpos,smb_maxcnt);
2165 return(UNIXERROR(ERRDOS,ERRnoaccess));
2167 SSVAL(outbuf,smb_vwv5,nread);
2168 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
2169 SSVAL(smb_buf(outbuf),-2,nread);
2171 DEBUG( 3, ( "readX fnum=%d min=%d max=%d nread=%d\n",
2172 fsp->fnum, smb_mincnt, smb_maxcnt, nread ) );
2174 return chain_reply(inbuf,outbuf,length,bufsize);
2177 /****************************************************************************
2178 reply to a writebraw (core+ or LANMAN1.0 protocol)
2179 ****************************************************************************/
2180 int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2183 ssize_t total_written=0;
2184 size_t numtowrite=0;
2189 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2192 CHECK_FSP(fsp,conn);
2196 tcount = IVAL(inbuf,smb_vwv1);
2197 startpos = IVAL(inbuf,smb_vwv3);
2198 write_through = BITSETW(inbuf+smb_vwv7,0);
2200 /* We have to deal with slightly different formats depending
2201 on whether we are using the core+ or lanman1.0 protocol */
2202 if(Protocol <= PROTOCOL_COREPLUS) {
2203 numtowrite = SVAL(smb_buf(inbuf),-2);
2204 data = smb_buf(inbuf);
2206 numtowrite = SVAL(inbuf,smb_vwv10);
2207 data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
2210 /* force the error type */
2211 CVAL(inbuf,smb_com) = SMBwritec;
2212 CVAL(outbuf,smb_com) = SMBwritec;
2214 if (is_locked(fsp,conn,tcount,startpos, F_WRLCK))
2215 return(ERROR(ERRDOS,ERRlock));
2217 if (seek_file(fsp,startpos) == -1) {
2218 DEBUG(0,("couldn't seek to %.0f in writebraw\n",(double)startpos));
2219 return(UNIXERROR(ERRDOS,ERRnoaccess));
2223 nwritten = write_file(fsp,data,numtowrite);
2225 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
2226 fsp->fnum, (double)startpos, numtowrite, nwritten, write_through));
2228 if (nwritten < numtowrite)
2229 return(UNIXERROR(ERRHRD,ERRdiskfull));
2231 total_written = nwritten;
2233 /* Return a message to the redirector to tell it
2234 to send more bytes */
2235 CVAL(outbuf,smb_com) = SMBwritebraw;
2236 SSVALS(outbuf,smb_vwv0,-1);
2237 outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
2238 send_smb(Client,outbuf);
2240 /* Now read the raw data into the buffer and write it */
2241 if (read_smb_length(Client,inbuf,SMB_SECONDARY_WAIT) == -1) {
2242 exit_server("secondary writebraw failed");
2245 /* Even though this is not an smb message, smb_len
2246 returns the generic length of an smb message */
2247 numtowrite = smb_len(inbuf);
2249 if (tcount > nwritten+numtowrite) {
2250 DEBUG(3,("Client overestimated the write %d %d %d\n",
2251 tcount,nwritten,numtowrite));
2254 nwritten = vfs_transfer_file(Client, NULL, -1, fsp,
2255 (SMB_OFF_T)numtowrite,NULL,0,
2257 total_written += nwritten;
2259 /* Set up outbuf to return the correct return */
2260 outsize = set_message(outbuf,1,0,True);
2261 CVAL(outbuf,smb_com) = SMBwritec;
2262 SSVAL(outbuf,smb_vwv0,total_written);
2264 if (nwritten < (ssize_t)numtowrite) {
2265 CVAL(outbuf,smb_rcls) = ERRHRD;
2266 SSVAL(outbuf,smb_err,ERRdiskfull);
2269 if ((lp_syncalways(SNUM(conn)) || write_through) &&
2270 lp_strict_sync(SNUM(conn)))
2271 conn->vfs_ops.sync(fsp->fd_ptr->fd);
2273 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
2274 fsp->fnum, (double)startpos, numtowrite, total_written));
2276 /* we won't return a status if write through is not selected - this
2277 follows what WfWg does */
2278 if (!write_through && total_written==tcount)
2284 /****************************************************************************
2285 reply to a writeunlock (core+)
2286 ****************************************************************************/
2287 int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2289 ssize_t nwritten = -1;
2295 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2298 CHECK_FSP(fsp,conn);
2302 numtowrite = SVAL(inbuf,smb_vwv1);
2303 startpos = IVAL(inbuf,smb_vwv2);
2304 data = smb_buf(inbuf) + 3;
2306 if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
2307 return(ERROR(ERRDOS,ERRlock));
2309 if(seek_file(fsp,startpos) == -1)
2310 return(UNIXERROR(ERRDOS,ERRnoaccess));
2312 /* The special X/Open SMB protocol handling of
2313 zero length writes is *NOT* done for
2318 nwritten = write_file(fsp,data,numtowrite);
2320 if (lp_syncalways(SNUM(conn)) && lp_strict_sync(SNUM(conn)))
2321 conn->vfs_ops.sync(fsp->fd_ptr->fd);
2323 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
2324 return(UNIXERROR(ERRDOS,ERRnoaccess));
2326 if(!do_unlock(fsp, conn, numtowrite, startpos, &eclass, &ecode))
2327 return(ERROR(eclass,ecode));
2329 outsize = set_message(outbuf,1,0,True);
2331 SSVAL(outbuf,smb_vwv0,nwritten);
2333 DEBUG( 3, ( "writeunlock fnum=%d num=%d wrote=%d\n",
2334 fsp->fnum, numtowrite, nwritten ) );
2339 /****************************************************************************
2341 ****************************************************************************/
2342 int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,int dum_buffsize)
2345 ssize_t nwritten = -1;
2348 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2351 /* If it's an IPC, pass off the pipe handler. */
2353 return reply_pipe_write(inbuf,outbuf,dum_size,dum_buffsize);
2355 CHECK_FSP(fsp,conn);
2359 numtowrite = SVAL(inbuf,smb_vwv1);
2360 startpos = IVAL(inbuf,smb_vwv2);
2361 data = smb_buf(inbuf) + 3;
2363 if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
2364 return(ERROR(ERRDOS,ERRlock));
2366 if(seek_file(fsp,startpos) == -1)
2367 return(UNIXERROR(ERRDOS,ERRnoaccess));
2369 /* X/Open SMB protocol says that if smb_vwv1 is
2370 zero then the file size should be extended or
2371 truncated to the size given in smb_vwv[2-3] */
2373 nwritten = set_filelen(fsp->fd_ptr->fd, (SMB_OFF_T)startpos);
2375 nwritten = write_file(fsp,data,numtowrite);
2377 if (lp_syncalways(SNUM(conn)) && lp_strict_sync(SNUM(conn)))
2378 conn->vfs_ops.sync(fsp->fd_ptr->fd);
2380 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
2381 return(UNIXERROR(ERRDOS,ERRnoaccess));
2383 outsize = set_message(outbuf,1,0,True);
2385 SSVAL(outbuf,smb_vwv0,nwritten);
2387 if (nwritten < (ssize_t)numtowrite) {
2388 CVAL(outbuf,smb_rcls) = ERRHRD;
2389 SSVAL(outbuf,smb_err,ERRdiskfull);
2392 DEBUG(3,("write fnum=%d num=%d wrote=%d\n",
2393 fsp->fnum, numtowrite, nwritten));
2399 /****************************************************************************
2400 reply to a write and X
2401 ****************************************************************************/
2402 int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
2404 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
2405 SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3);
2406 size_t numtowrite = SVAL(inbuf,smb_vwv10);
2407 BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
2408 ssize_t nwritten = -1;
2409 int smb_doff = SVAL(inbuf,smb_vwv11);
2412 /* If it's an IPC, pass off the pipe handler. */
2414 return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
2416 CHECK_FSP(fsp,conn);
2420 data = smb_base(inbuf) + smb_doff;
2422 #ifdef LARGE_SMB_OFF_T
2423 if(CVAL(inbuf,smb_wct) == 14) {
2425 * This is a large offset (64 bit) write.
2427 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
2429 #endif /* LARGE_SMB_OFF_T */
2431 if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
2432 return(ERROR(ERRDOS,ERRlock));
2434 if(seek_file(fsp,startpos) == -1)
2435 return(UNIXERROR(ERRDOS,ERRnoaccess));
2437 /* X/Open SMB protocol says that, unlike SMBwrite
2438 if the length is zero then NO truncation is
2439 done, just a write of zero. To truncate a file,
2444 nwritten = write_file(fsp,data,numtowrite);
2446 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
2447 return(UNIXERROR(ERRDOS,ERRnoaccess));
2449 set_message(outbuf,6,0,True);
2451 SSVAL(outbuf,smb_vwv2,nwritten);
2453 if (nwritten < (ssize_t)numtowrite) {
2454 CVAL(outbuf,smb_rcls) = ERRHRD;
2455 SSVAL(outbuf,smb_err,ERRdiskfull);
2458 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
2459 fsp->fnum, numtowrite, nwritten));
2461 if ((lp_syncalways(SNUM(conn)) || write_through) &&
2462 lp_strict_sync(SNUM(conn)))
2463 conn->vfs_ops.sync(fsp->fd_ptr->fd);
2465 return chain_reply(inbuf,outbuf,length,bufsize);
2469 /****************************************************************************
2471 ****************************************************************************/
2472 int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2478 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2480 CHECK_FSP(fsp,conn);
2483 mode = SVAL(inbuf,smb_vwv1) & 3;
2484 startpos = IVAL(inbuf,smb_vwv2);
2488 case 0: umode = SEEK_SET; break;
2489 case 1: umode = SEEK_CUR; break;
2490 case 2: umode = SEEK_END; break;
2492 umode = SEEK_SET; break;
2495 if((res = conn->vfs_ops.lseek(fsp->fd_ptr->fd,startpos,umode)) == -1)
2496 return(UNIXERROR(ERRDOS,ERRnoaccess));
2500 outsize = set_message(outbuf,2,0,True);
2501 SIVALS(outbuf,smb_vwv0,res);
2503 DEBUG(3,("lseek fnum=%d ofs=%.0f mode=%d\n",
2504 fsp->fnum, (double)startpos, mode));
2509 /****************************************************************************
2511 ****************************************************************************/
2512 int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2514 int outsize = set_message(outbuf,0,0,True);
2515 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2518 CHECK_FSP(fsp,conn);
2523 file_sync_all(conn);
2525 conn->vfs_ops.sync(fsp->fd_ptr->fd);
2528 DEBUG(3,("flush\n"));
2533 /****************************************************************************
2535 ****************************************************************************/
2536 int reply_exit(connection_struct *conn,
2537 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2539 int outsize = set_message(outbuf,0,0,True);
2540 DEBUG(3,("exit\n"));
2546 /****************************************************************************
2547 Reply to a close - has to deal with closing a directory opened by NT SMB's.
2548 ****************************************************************************/
2549 int reply_close(connection_struct *conn,
2550 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2554 int32 eclass = 0, err = 0;
2555 files_struct *fsp = NULL;
2557 outsize = set_message(outbuf,0,0,True);
2559 /* If it's an IPC, pass off to the pipe handler. */
2561 return reply_pipe_close(conn, inbuf,outbuf);
2564 fsp = file_fsp(inbuf,smb_vwv0);
2567 * We can only use CHECK_FSP if we know it's not a directory.
2570 if(!fsp || !fsp->open || (fsp->conn != conn))
2571 return(ERROR(ERRDOS,ERRbadfid));
2573 if(HAS_CACHED_ERROR(fsp)) {
2574 eclass = fsp->wbmpx_ptr->wr_errclass;
2575 err = fsp->wbmpx_ptr->wr_error;
2578 if(fsp->is_directory) {
2580 * Special case - close NT SMB directory
2583 DEBUG(3,("close directory fnum=%d\n", fsp->fnum));
2584 close_directory(fsp);
2587 * Close ordinary file.
2591 * If there was a modify time outstanding,
2592 * try and set it here.
2594 if(fsp->pending_modtime)
2595 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
2598 * Now take care of any time sent in the close.
2600 mtime = make_unix_date3(inbuf+smb_vwv1);
2602 /* try and set the date */
2603 set_filetime(conn, fsp->fsp_name,mtime);
2605 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
2606 fsp->fd_ptr->fd, fsp->fnum,
2607 conn->num_files_open));
2609 close_file(fsp,True);
2612 /* We have a cached error */
2614 return(ERROR(eclass,err));
2620 /****************************************************************************
2621 reply to a writeclose (Core+ protocol)
2622 ****************************************************************************/
2623 int reply_writeclose(connection_struct *conn,
2624 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2627 ssize_t nwritten = -1;
2632 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2634 CHECK_FSP(fsp,conn);
2638 numtowrite = SVAL(inbuf,smb_vwv1);
2639 startpos = IVAL(inbuf,smb_vwv2);
2640 mtime = make_unix_date3(inbuf+smb_vwv4);
2641 data = smb_buf(inbuf) + 1;
2643 if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
2644 return(ERROR(ERRDOS,ERRlock));
2646 if(seek_file(fsp,startpos) == -1)
2647 return(UNIXERROR(ERRDOS,ERRnoaccess));
2649 nwritten = write_file(fsp,data,numtowrite);
2651 set_filetime(conn, fsp->fsp_name,mtime);
2653 close_file(fsp,True);
2655 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
2656 fsp->fnum, numtowrite, nwritten,
2657 conn->num_files_open));
2660 return(UNIXERROR(ERRDOS,ERRnoaccess));
2662 outsize = set_message(outbuf,1,0,True);
2664 SSVAL(outbuf,smb_vwv0,nwritten);
2669 /****************************************************************************
2671 ****************************************************************************/
2672 int reply_lock(connection_struct *conn,
2673 char *inbuf,char *outbuf, int length, int dum_buffsize)
2675 int outsize = set_message(outbuf,0,0,True);
2676 SMB_OFF_T count,offset;
2679 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2681 CHECK_FSP(fsp,conn);
2684 count = IVAL(inbuf,smb_vwv1);
2685 offset = IVAL(inbuf,smb_vwv3);
2687 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2688 fsp->fd_ptr->fd, fsp->fnum, (double)offset, (double)count));
2690 if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode)) {
2691 if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) {
2693 * A blocking lock was requested. Package up
2694 * this smb into a queued request and push it
2695 * onto the blocking lock queue.
2697 if(push_blocking_lock_request(inbuf, length, -1, 0))
2700 return (ERROR(eclass,ecode));
2707 /****************************************************************************
2709 ****************************************************************************/
2710 int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2712 int outsize = set_message(outbuf,0,0,True);
2713 SMB_OFF_T count,offset;
2716 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2718 CHECK_FSP(fsp,conn);
2721 count = IVAL(inbuf,smb_vwv1);
2722 offset = IVAL(inbuf,smb_vwv3);
2724 if(!do_unlock(fsp, conn, count, offset, &eclass, &ecode))
2725 return (ERROR(eclass,ecode));
2727 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
2728 fsp->fd_ptr->fd, fsp->fnum, (double)offset, (double)count ) );
2734 /****************************************************************************
2736 ****************************************************************************/
2737 int reply_tdis(connection_struct *conn,
2738 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2740 int outsize = set_message(outbuf,0,0,True);
2743 vuid = SVAL(inbuf,smb_uid);
2746 DEBUG(4,("Invalid connection in tdis\n"));
2747 return(ERROR(ERRSRV,ERRinvnid));
2752 close_cnum(conn,vuid);
2759 /****************************************************************************
2761 ****************************************************************************/
2762 int reply_echo(connection_struct *conn,
2763 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2765 int smb_reverb = SVAL(inbuf,smb_vwv0);
2767 int data_len = smb_buflen(inbuf);
2768 int outsize = set_message(outbuf,1,data_len,True);
2770 /* copy any incoming data back out */
2772 memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
2774 if (smb_reverb > 100) {
2775 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
2779 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
2780 SSVAL(outbuf,smb_vwv0,seq_num);
2782 smb_setlen(outbuf,outsize - 4);
2784 send_smb(Client,outbuf);
2787 DEBUG(3,("echo %d times\n", smb_reverb));
2793 /****************************************************************************
2794 reply to a printopen
2795 ****************************************************************************/
2796 int reply_printopen(connection_struct *conn,
2797 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2804 *fname = *fname2 = 0;
2806 if (!CAN_PRINT(conn))
2807 return(ERROR(ERRDOS,ERRnoaccess));
2812 pstrcpy(s,smb_buf(inbuf)+1);
2815 if (!(isalnum((int)*p) || strchr("._-",*p)))
2820 if (strlen(s) > 10) s[10] = 0;
2822 slprintf(fname,sizeof(fname)-1, "%s.XXXXXX",s);
2827 return(ERROR(ERRSRV,ERRnofids));
2829 pstrcpy(fname2,(char *)mktemp(fname));
2831 if (!check_name(fname2,conn)) {
2833 return(ERROR(ERRDOS,ERRnoaccess));
2836 /* Open for exclusive use, write only. */
2837 open_file_shared(fsp,conn,fname2, SET_DENY_MODE(DENY_ALL)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
2838 (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unix_mode(conn,0), 0, NULL, NULL);
2842 return(UNIXERROR(ERRDOS,ERRnoaccess));
2845 /* force it to be a print file */
2846 fsp->print_file = True;
2848 outsize = set_message(outbuf,1,0,True);
2849 SSVAL(outbuf,smb_vwv0,fsp->fnum);
2851 DEBUG(3,("openprint %s fd=%d fnum=%d\n",
2852 fname2, fsp->fd_ptr->fd, fsp->fnum));
2858 /****************************************************************************
2859 reply to a printclose
2860 ****************************************************************************/
2861 int reply_printclose(connection_struct *conn,
2862 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2864 int outsize = set_message(outbuf,0,0,True);
2865 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2867 CHECK_FSP(fsp,conn);
2870 if (!CAN_PRINT(conn))
2871 return(ERROR(ERRDOS,ERRnoaccess));
2873 DEBUG(3,("printclose fd=%d fnum=%d\n",
2874 fsp->fd_ptr->fd,fsp->fnum));
2876 close_file(fsp,True);
2882 /****************************************************************************
2883 reply to a printqueue
2884 ****************************************************************************/
2885 int reply_printqueue(connection_struct *conn,
2886 char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2888 int outsize = set_message(outbuf,2,3,True);
2889 int max_count = SVAL(inbuf,smb_vwv0);
2890 int start_index = SVAL(inbuf,smb_vwv1);
2892 /* we used to allow the client to get the cnum wrong, but that
2893 is really quite gross and only worked when there was only
2894 one printer - I think we should now only accept it if they
2895 get it right (tridge) */
2896 if (!CAN_PRINT(conn))
2897 return(ERROR(ERRDOS,ERRnoaccess));
2899 SSVAL(outbuf,smb_vwv0,0);
2900 SSVAL(outbuf,smb_vwv1,0);
2901 CVAL(smb_buf(outbuf),0) = 1;
2902 SSVAL(smb_buf(outbuf),1,0);
2904 DEBUG(3,("printqueue start_index=%d max_count=%d\n",
2905 start_index, max_count));
2908 print_queue_struct *queue = NULL;
2909 char *p = smb_buf(outbuf) + 3;
2910 int count = get_printqueue(SNUM(conn), conn,&queue,NULL);
2911 int num_to_get = ABS(max_count);
2912 int first = (max_count>0?start_index:start_index+max_count+1);
2918 num_to_get = MIN(num_to_get,count-first);
2921 for (i=first;i<first+num_to_get;i++) {
2922 put_dos_date2(p,0,queue[i].time);
2923 CVAL(p,4) = (queue[i].status==LPQ_PRINTING?2:3);
2924 SSVAL(p,5,printjob_encode(SNUM(conn),
2926 SIVAL(p,7,queue[i].size);
2928 StrnCpy(p+12,queue[i].user,16);
2933 outsize = set_message(outbuf,2,28*count+3,False);
2934 SSVAL(outbuf,smb_vwv0,count);
2935 SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
2936 CVAL(smb_buf(outbuf),0) = 1;
2937 SSVAL(smb_buf(outbuf),1,28*count);
2940 if (queue) free(queue);
2942 DEBUG(3,("%d entries returned in queue\n",count));
2949 /****************************************************************************
2950 reply to a printwrite
2951 ****************************************************************************/
2952 int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2955 int outsize = set_message(outbuf,0,0,True);
2957 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
2959 if (!CAN_PRINT(conn))
2960 return(ERROR(ERRDOS,ERRnoaccess));
2962 CHECK_FSP(fsp,conn);
2966 numtowrite = SVAL(smb_buf(inbuf),1);
2967 data = smb_buf(inbuf) + 3;
2969 if (write_file(fsp,data,numtowrite) != numtowrite)
2970 return(UNIXERROR(ERRDOS,ERRnoaccess));
2972 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
2978 /****************************************************************************
2980 ****************************************************************************/
2981 int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
2984 int outsize,ret= -1;
2985 BOOL bad_path = False;
2987 pstrcpy(directory,smb_buf(inbuf) + 1);
2988 if (!unix_dfs_convert(directory,conn,0,&bad_path,NULL))
2990 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
2991 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
2994 if (check_name(directory, conn))
2995 ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False),
2996 unix_mode(conn,aDIR));
3000 if((errno == ENOENT) && bad_path)
3002 unix_ERR_class = ERRDOS;
3003 unix_ERR_code = ERRbadpath;
3005 return(UNIXERROR(ERRDOS,ERRnoaccess));
3008 outsize = set_message(outbuf,0,0,True);
3010 DEBUG( 3, ( "mkdir %s ret=%d\n", directory, ret ) );
3015 /****************************************************************************
3016 Static function used by reply_rmdir to delete an entire directory
3018 ****************************************************************************/
3019 static BOOL recursive_rmdir(connection_struct *conn, char *directory)
3023 void *dirptr = OpenDir(conn, directory, False);
3028 while((dname = ReadDirName(dirptr)))
3033 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3036 /* Construct the full name. */
3037 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
3043 pstrcpy(fullname, directory);
3044 pstrcat(fullname, "/");
3045 pstrcat(fullname, dname);
3047 if(conn->vfs_ops.lstat(fullname, &st) != 0)
3053 if(st.st_mode & S_IFDIR)
3055 if(recursive_rmdir(conn, fullname)!=0)
3060 if(conn->vfs_ops.rmdir(dos_to_unix(fullname,False)) != 0)
3066 else if(conn->vfs_ops.unlink(dos_to_unix(fullname,False)) != 0)
3076 /****************************************************************************
3078 ****************************************************************************/
3079 int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3084 BOOL bad_path = False;
3086 pstrcpy(directory,smb_buf(inbuf) + 1);
3087 if (!unix_dfs_convert(directory,conn, NULL,&bad_path,NULL))
3089 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
3090 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
3093 if (check_name(directory,conn))
3096 dptr_closepath(directory,SVAL(inbuf,smb_pid));
3097 ok = (conn->vfs_ops.rmdir(dos_to_unix(directory,False)) == 0);
3098 if(!ok && (errno == ENOTEMPTY) && lp_veto_files(SNUM(conn)))
3100 /* Check to see if the only thing in this directory are
3101 vetoed files/directories. If so then delete them and
3102 retry. If we fail to delete any of them (and we *don't*
3103 do a recursive delete) then fail the rmdir. */
3104 BOOL all_veto_files = True;
3106 void *dirptr = OpenDir(conn, directory, False);
3110 int dirpos = TellDir(dirptr);
3111 while ((dname = ReadDirName(dirptr)))
3113 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3115 if(!IS_VETO_PATH(conn, dname))
3117 all_veto_files = False;
3123 SeekDir(dirptr,dirpos);
3124 while ((dname = ReadDirName(dirptr)))
3129 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
3132 /* Construct the full name. */
3133 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
3138 pstrcpy(fullname, directory);
3139 pstrcat(fullname, "/");
3140 pstrcat(fullname, dname);
3142 if(conn->vfs_ops.lstat(fullname, &st) != 0)
3144 if(st.st_mode & S_IFDIR)
3146 if(lp_recursive_veto_delete(SNUM(conn)))
3148 DEBUG(0, ("ERROR: recursive_rmdir()\n"));
3149 if(recursive_rmdir(conn, fullname) != 0)
3152 if(conn->vfs_ops.rmdir(dos_to_unix(fullname,False)) != 0)
3155 else if(conn->vfs_ops.unlink(dos_to_unix(fullname,False)) != 0)
3159 /* Retry the rmdir */
3160 ok = (conn->vfs_ops.rmdir(dos_to_unix(directory,False)) == 0);
3170 DEBUG(3,("couldn't remove directory %s : %s\n",
3171 directory,strerror(errno)));
3176 if((errno == ENOENT) && bad_path)
3178 unix_ERR_class = ERRDOS;
3179 unix_ERR_code = ERRbadpath;
3181 return(UNIXERROR(ERRDOS,ERRbadpath));
3184 outsize = set_message(outbuf,0,0,True);
3186 DEBUG( 3, ( "rmdir %s\n", directory ) );
3192 /*******************************************************************
3193 resolve wildcards in a filename rename
3194 ********************************************************************/
3195 static BOOL resolve_wildcards(char *name1,char *name2)
3197 fstring root1,root2;
3201 name1 = strrchr(name1,'/');
3202 name2 = strrchr(name2,'/');
3204 if (!name1 || !name2) return(False);
3206 fstrcpy(root1,name1);
3207 fstrcpy(root2,name2);
3208 p = strrchr(root1,'.');
3215 p = strrchr(root2,'.');
3247 pstrcpy(name2,root2);
3250 pstrcat(name2,ext2);
3256 /*******************************************************************
3257 check if a user is allowed to rename a file
3258 ********************************************************************/
3259 static BOOL can_rename(char *fname,connection_struct *conn)
3261 SMB_STRUCT_STAT sbuf;
3263 if (!CAN_WRITE(conn)) return(False);
3265 if (conn->vfs_ops.lstat(fname,&sbuf) != 0) return(False);
3266 if (!check_file_sharing(conn,fname,True)) return(False);
3271 /****************************************************************************
3272 The guts of the rename command, split out so it may be called by the NT SMB
3274 ****************************************************************************/
3275 int rename_internals(connection_struct *conn,
3276 char *inbuf, char *outbuf, char *name,
3277 char *newname, BOOL replace_if_exists)
3281 pstring newname_last_component;
3284 BOOL bad_path1 = False;
3285 BOOL bad_path2 = False;
3287 int error = ERRnoaccess;
3290 *directory = *mask = 0;
3292 if (!unix_dfs_convert(name,conn,0,&bad_path1,NULL))
3294 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
3295 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
3297 if (!unix_dfs_convert(newname,conn,newname_last_component,&bad_path2,NULL))
3299 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
3300 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
3304 * Split the old name into directory and last component
3305 * strings. Note that if (!unix_dfs_convert may have stripped off a
3306 * leading ./ from both name and newname if the rename is
3307 * at the root of the share. We need to make sure either both
3308 * name and newname contain a / character or neither of them do
3309 * as this is checked in resolve_wildcards().
3312 p = strrchr(name,'/');
3314 pstrcpy(directory,".");
3318 pstrcpy(directory,name);
3320 *p = '/'; /* Replace needed for exceptional test below. */
3323 if (is_mangled(mask))
3324 check_mangled_cache( mask );
3326 has_wild = strchr(mask,'*') || strchr(mask,'?');
3330 * No wildcards - just process the one file.
3332 BOOL is_short_name = is_8_3(name, True);
3334 /* Add a terminating '/' to the directory name. */
3335 pstrcat(directory,"/");
3336 pstrcat(directory,mask);
3338 /* Ensure newname contains a '/' also */
3339 if(strrchr(newname,'/') == 0) {
3342 pstrcpy(tmpstr, "./");
3343 pstrcat(tmpstr, newname);
3344 pstrcpy(newname, tmpstr);
3347 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",
3348 case_sensitive, case_preserve, short_case_preserve, directory,
3349 newname, newname_last_component, is_short_name));
3352 * Check for special case with case preserving and not
3353 * case sensitive, if directory and newname are identical,
3354 * and the old last component differs from the original
3355 * last component only by case, then we should allow
3356 * the rename (user is trying to change the case of the
3359 if((case_sensitive == False) &&
3360 (((case_preserve == True) &&
3361 (is_short_name == False)) ||
3362 ((short_case_preserve == True) &&
3363 (is_short_name == True))) &&
3364 strcsequal(directory, newname)) {
3365 pstring newname_modified_last_component;
3368 * Get the last component of the modified name.
3369 * Note that we guarantee that newname contains a '/'
3372 p = strrchr(newname,'/');
3373 pstrcpy(newname_modified_last_component,p+1);
3375 if(strcsequal(newname_modified_last_component,
3376 newname_last_component) == False) {
3378 * Replace the modified last component with
3381 pstrcpy(p+1, newname_last_component);
3385 if(replace_if_exists) {
3387 * NT SMB specific flag - rename can overwrite
3388 * file with the same name so don't check for
3391 if(resolve_wildcards(directory,newname) &&
3392 can_rename(directory,conn) &&
3393 !conn->vfs_ops.rename(dos_to_unix(directory,False),
3397 if (resolve_wildcards(directory,newname) &&
3398 can_rename(directory,conn) &&
3399 !vfs_file_exist(conn,dos_to_unix(newname,False),NULL) &&
3400 !conn->vfs_ops.rename(dos_to_unix(directory,False),
3405 DEBUG(3,("rename_internals: %s doing rename on %s -> %s\n",(count != 0) ? "succeeded" : "failed",
3406 directory,newname));
3408 if (!count) exists = vfs_file_exist(conn,dos_to_unix(directory,False),NULL);
3409 if (!count && exists && vfs_file_exist(conn,dos_to_unix(newname,False),NULL)) {
3415 * Wildcards - process each file that matches.
3417 void *dirptr = NULL;
3421 if (check_name(directory,conn))
3422 dirptr = OpenDir(conn, directory, True);
3427 if (strequal(mask,"????????.???"))
3430 while ((dname = ReadDirName(dirptr))) {
3432 pstrcpy(fname,dname);
3434 if(!mask_match(fname, mask, case_sensitive, False))
3437 error = ERRnoaccess;
3438 slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname);
3439 if (!can_rename(fname,conn)) {
3440 DEBUG(6,("rename %s refused\n", fname));
3443 pstrcpy(destname,newname);
3445 if (!resolve_wildcards(fname,destname)) {
3446 DEBUG(6,("resolve_wildcards %s %s failed\n", fname, destname));
3450 if (!replace_if_exists && vfs_file_exist(conn,dos_to_unix(destname,False),NULL)) {
3451 DEBUG(6,("file_exist %s\n", destname));
3456 if (!conn->vfs_ops.rename(dos_to_unix(fname,False),destname))
3458 DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
3466 return(ERROR(ERRDOS,error));
3468 if((errno == ENOENT) && (bad_path1 || bad_path2)) {
3469 unix_ERR_class = ERRDOS;
3470 unix_ERR_code = ERRbadpath;
3472 return(UNIXERROR(ERRDOS,error));
3479 /****************************************************************************
3481 ****************************************************************************/
3483 int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3489 pstrcpy(name,smb_buf(inbuf) + 1);
3490 pstrcpy(newname,smb_buf(inbuf) + 3 + strlen(name));
3492 DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
3494 outsize = rename_internals(conn, inbuf, outbuf, name, newname, False);
3496 outsize = set_message(outbuf,0,0,True);
3501 /*******************************************************************
3502 copy a file as part of a reply_copy
3503 ******************************************************************/
3505 static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
3506 int count,BOOL target_is_directory)
3511 files_struct *fsp1,*fsp2;
3514 pstrcpy(dest,dest1);
3515 if (target_is_directory) {
3516 char *p = strrchr(src,'/');
3525 if (!vfs_file_exist(conn,dos_to_unix(src,False),&st))
3532 open_file_shared(fsp1, conn, src,
3533 SET_DENY_MODE(DENY_NONE) | SET_OPEN_MODE(DOS_OPEN_RDONLY),
3534 (FILE_FAIL_IF_NOT_EXIST | FILE_EXISTS_OPEN), 0, 0, &Access, &action);
3541 if (!target_is_directory && count)
3546 close_file(fsp1,False);
3549 open_file_shared(fsp2, conn, dest,
3550 SET_DENY_MODE(DENY_NONE) | SET_OPEN_MODE(DOS_OPEN_WRONLY),
3551 ofun, st.st_mode, 0, &Access, &action);
3554 close_file(fsp1,False);
3559 if ((ofun&3) == 1) {
3560 if(conn->vfs_ops.lseek(fsp2->fd_ptr->fd,0,SEEK_END) == -1) {
3561 DEBUG(0,("copy_file: error - sys_lseek returned error %s\n",
3564 * Stop the copy from occurring.
3572 ret = vfs_transfer_file(-1, fsp1, -1, fsp2, st.st_size, NULL, 0, 0);
3574 close_file(fsp1,False);
3575 close_file(fsp2,False);
3577 return(ret == st.st_size);
3582 /****************************************************************************
3583 reply to a file copy.
3584 ****************************************************************************/
3585 int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3590 pstring mask,newname;
3593 int error = ERRnoaccess;
3596 int tid2 = SVAL(inbuf,smb_vwv0);
3597 int ofun = SVAL(inbuf,smb_vwv1);
3598 int flags = SVAL(inbuf,smb_vwv2);
3599 BOOL target_is_directory=False;
3600 BOOL bad_path1 = False;
3601 BOOL bad_path2 = False;
3603 *directory = *mask = 0;
3605 pstrcpy(name,smb_buf(inbuf));
3606 pstrcpy(newname,smb_buf(inbuf) + 1 + strlen(name));
3608 DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
3610 if (tid2 != conn->cnum) {
3611 /* can't currently handle inter share copies XXXX */
3612 DEBUG(3,("Rejecting inter-share copy\n"));
3613 return(ERROR(ERRSRV,ERRinvdevice));
3616 if (!unix_dfs_convert(name,conn,0,&bad_path1,NULL))
3618 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
3619 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
3621 if (!unix_dfs_convert(newname,conn,0,&bad_path2,NULL))
3623 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
3624 return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
3627 target_is_directory = dos_directory_exist(newname,NULL);
3629 if ((flags&1) && target_is_directory) {
3630 return(ERROR(ERRDOS,ERRbadfile));
3633 if ((flags&2) && !target_is_directory) {
3634 return(ERROR(ERRDOS,ERRbadpath));
3637 if ((flags&(1<<5)) && dos_directory_exist(name,NULL)) {
3638 /* wants a tree copy! XXXX */
3639 DEBUG(3,("Rejecting tree copy\n"));
3640 return(ERROR(ERRSRV,ERRerror));
3643 p = strrchr(name,'/');
3645 pstrcpy(directory,"./");
3649 pstrcpy(directory,name);
3653 if (is_mangled(mask))
3654 check_mangled_cache( mask );
3656 has_wild = strchr(mask,'*') || strchr(mask,'?');
3659 pstrcat(directory,"/");
3660 pstrcat(directory,mask);
3661 if (resolve_wildcards(directory,newname) &&
3662 copy_file(directory,newname,conn,ofun,
3663 count,target_is_directory)) count++;
3664 if (!count) exists = vfs_file_exist(conn,dos_to_unix(directory,False),NULL);
3666 void *dirptr = NULL;
3670 if (check_name(directory,conn))
3671 dirptr = OpenDir(conn, directory, True);
3677 if (strequal(mask,"????????.???"))
3680 while ((dname = ReadDirName(dirptr)))
3683 pstrcpy(fname,dname);
3685 if(!mask_match(fname, mask, case_sensitive, False)) continue;
3687 error = ERRnoaccess;
3688 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
3689 pstrcpy(destname,newname);
3690 if (resolve_wildcards(fname,destname) &&
3691 copy_file(directory,newname,conn,ofun,
3692 count,target_is_directory)) count++;
3693 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
3701 return(ERROR(ERRDOS,error));
3704 if((errno == ENOENT) && (bad_path1 || bad_path2))
3706 unix_ERR_class = ERRDOS;
3707 unix_ERR_code = ERRbadpath;
3709 return(UNIXERROR(ERRDOS,error));
3713 outsize = set_message(outbuf,1,0,True);
3714 SSVAL(outbuf,smb_vwv0,count);
3719 /****************************************************************************
3721 ****************************************************************************/
3722 int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3730 if (!CAN_SETDIR(snum))
3731 return(ERROR(ERRDOS,ERRnoaccess));
3733 pstrcpy(newdir,smb_buf(inbuf) + 1);
3736 if (strlen(newdir) == 0) {
3739 ok = dos_directory_exist(newdir,NULL);
3741 string_set(&conn->connectpath,newdir);
3746 return(ERROR(ERRDOS,ERRbadpath));
3748 outsize = set_message(outbuf,0,0,True);
3749 CVAL(outbuf,smb_reh) = CVAL(inbuf,smb_reh);
3751 DEBUG(3,("setdir %s\n", newdir));
3756 /****************************************************************************
3757 reply to a lockingX request
3758 ****************************************************************************/
3759 int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
3761 files_struct *fsp = file_fsp(inbuf,smb_vwv2);
3762 unsigned char locktype = CVAL(inbuf,smb_vwv3);
3764 unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
3766 uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
3767 uint16 num_locks = SVAL(inbuf,smb_vwv7);
3768 SMB_OFF_T count = 0, offset = 0;
3769 int32 lock_timeout = IVAL(inbuf,smb_vwv4);
3772 uint32 ecode=0, dummy2;
3773 int eclass=0, dummy1;
3774 BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
3775 CHECK_FSP(fsp,conn);
3778 data = smb_buf(inbuf);
3780 /* Check if this is an oplock break on a file
3781 we have granted an oplock on.
3783 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE))
3786 SMB_DEV_T dev = fsp->fd_ptr->dev;
3787 SMB_INO_T inode = fsp->fd_ptr->inode;
3789 DEBUG(5,("reply_lockingX: oplock break reply from client for fnum = %d\n",
3792 * Make sure we have granted an oplock on this file.
3794 if(!fsp->granted_oplock)
3796 DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
3797 no oplock granted on this file.\n", fsp->fnum));
3798 return ERROR(ERRDOS,ERRlock);
3801 /* Remove the oplock flag from the sharemode. */
3802 lock_share_entry(fsp->conn, dev, inode, &token);
3803 if(remove_share_oplock(token, fsp)==False) {
3805 DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \
3806 dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
3808 unlock_share_entry(fsp->conn, dev, inode, token);
3810 unlock_share_entry(fsp->conn, dev, inode, token);
3812 /* Clear the granted flag and return. */
3813 fsp->granted_oplock = False;
3816 /* if this is a pure oplock break request then don't send a reply */
3817 if (num_locks == 0 && num_ulocks == 0)
3819 /* Sanity check - ensure a pure oplock break is not a
3821 if(CVAL(inbuf,smb_vwv0) != 0xff)
3822 DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
3823 (unsigned int)CVAL(inbuf,smb_vwv0) ));
3828 /* Data now points at the beginning of the list
3829 of smb_unlkrng structs */
3830 for(i = 0; i < (int)num_ulocks; i++) {
3831 if(!large_file_format) {
3832 count = IVAL(data,SMB_LKLEN_OFFSET(i));
3833 offset = IVAL(data,SMB_LKOFF_OFFSET(i));
3835 #ifdef LARGE_SMB_OFF_T
3837 count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) |
3838 ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i)));
3839 offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
3840 ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
3842 #endif /* LARGE_SMB_OFF_T */
3844 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for file %s\n",
3845 (double)offset, (double)count, fsp->fsp_name ));
3847 if(!do_unlock(fsp,conn,count,offset,&eclass, &ecode))
3848 return ERROR(eclass,ecode);
3851 /* Setup the timeout in seconds. */
3852 lock_timeout = ((lock_timeout == -1) ? -1 : lock_timeout/1000);
3854 /* Now do any requested locks */
3855 data += ((large_file_format ? 20 : 10)*num_ulocks);
3857 /* Data now points at the beginning of the list
3858 of smb_lkrng structs */
3860 for(i = 0; i < (int)num_locks; i++) {
3861 if(!large_file_format) {
3862 count = IVAL(data,SMB_LKLEN_OFFSET(i));
3863 offset = IVAL(data,SMB_LKOFF_OFFSET(i));
3865 #ifdef LARGE_SMB_OFF_T
3867 count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) |
3868 ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i)));
3869 offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
3870 ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
3872 #endif /* LARGE_SMB_OFF_T */
3874 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for file %s\n",
3875 (double)offset, (double)count, fsp->fsp_name ));
3877 if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
3879 if((ecode == ERRlock) && (lock_timeout != 0) && lp_blocking_locks(SNUM(conn))) {
3881 * A blocking lock was requested. Package up
3882 * this smb into a queued request and push it
3883 * onto the blocking lock queue.
3885 if(push_blocking_lock_request(inbuf, length, lock_timeout, i))
3892 /* If any of the above locks failed, then we must unlock
3893 all of the previous locks (X/Open spec). */
3894 if(i != num_locks && num_locks != 0) {
3895 for(; i >= 0; i--) {
3896 if(!large_file_format) {
3897 count = IVAL(data,SMB_LKLEN_OFFSET(i));
3898 offset = IVAL(data,SMB_LKOFF_OFFSET(i));
3900 #ifdef LARGE_SMB_OFF_T
3902 count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) |
3903 ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i)));
3904 offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
3905 ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
3907 #endif /* LARGE_SMB_OFF_T */
3909 do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
3911 return ERROR(eclass,ecode);
3914 set_message(outbuf,2,0,True);
3916 DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
3917 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
3919 return chain_reply(inbuf,outbuf,length,bufsize);
3923 /****************************************************************************
3924 reply to a SMBreadbmpx (read block multiplex) request
3925 ****************************************************************************/
3926 int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
3937 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
3939 /* this function doesn't seem to work - disable by default */
3941 return(ERROR(ERRSRV,ERRuseSTD));
3943 outsize = set_message(outbuf,8,0,True);
3945 CHECK_FSP(fsp,conn);
3949 startpos = IVAL(inbuf,smb_vwv1);
3950 maxcount = SVAL(inbuf,smb_vwv3);
3952 data = smb_buf(outbuf);
3953 pad = ((long)data)%4;
3954 if (pad) pad = 4 - pad;
3957 max_per_packet = bufsize-(outsize+pad);
3961 if (is_locked(fsp,conn,maxcount,startpos, F_RDLCK))
3962 return(ERROR(ERRDOS,ERRlock));
3966 size_t N = MIN(max_per_packet,tcount-total_read);
3968 nread = read_file(fsp,data,startpos,N);
3970 if (nread <= 0) nread = 0;
3972 if (nread < (ssize_t)N)
3973 tcount = total_read + nread;
3975 set_message(outbuf,8,nread,False);
3976 SIVAL(outbuf,smb_vwv0,startpos);
3977 SSVAL(outbuf,smb_vwv2,tcount);
3978 SSVAL(outbuf,smb_vwv6,nread);
3979 SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
3981 send_smb(Client,outbuf);
3983 total_read += nread;
3986 while (total_read < (ssize_t)tcount);
3991 /****************************************************************************
3992 reply to a SMBwritebmpx (write block multiplex primary) request
3993 ****************************************************************************/
3994 int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
3997 ssize_t nwritten = -1;
4004 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4006 CHECK_FSP(fsp,conn);
4010 tcount = SVAL(inbuf,smb_vwv1);
4011 startpos = IVAL(inbuf,smb_vwv3);
4012 write_through = BITSETW(inbuf+smb_vwv7,0);
4013 numtowrite = SVAL(inbuf,smb_vwv10);
4014 smb_doff = SVAL(inbuf,smb_vwv11);
4016 data = smb_base(inbuf) + smb_doff;
4018 /* If this fails we need to send an SMBwriteC response,
4019 not an SMBwritebmpx - set this up now so we don't forget */
4020 CVAL(outbuf,smb_com) = SMBwritec;
4022 if (is_locked(fsp,conn,tcount,startpos,F_WRLCK))
4023 return(ERROR(ERRDOS,ERRlock));
4025 if(seek_file(fsp,startpos) == -1)
4026 return(UNIXERROR(ERRDOS,ERRnoaccess));
4028 nwritten = write_file(fsp,data,numtowrite);
4030 if((lp_syncalways(SNUM(conn)) || write_through) &&
4031 lp_strict_sync(SNUM(conn)))
4032 conn->vfs_ops.sync(fsp->fd_ptr->fd);
4034 if(nwritten < (ssize_t)numtowrite)
4035 return(UNIXERROR(ERRHRD,ERRdiskfull));
4037 /* If the maximum to be written to this file
4038 is greater than what we just wrote then set
4039 up a secondary struct to be attached to this
4040 fd, we will use this to cache error messages etc. */
4041 if((ssize_t)tcount > nwritten)
4043 write_bmpx_struct *wbms;
4044 if(fsp->wbmpx_ptr != NULL)
4045 wbms = fsp->wbmpx_ptr; /* Use an existing struct */
4047 wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
4050 DEBUG(0,("Out of memory in reply_readmpx\n"));
4051 return(ERROR(ERRSRV,ERRnoresource));
4053 wbms->wr_mode = write_through;
4054 wbms->wr_discard = False; /* No errors yet */
4055 wbms->wr_total_written = nwritten;
4056 wbms->wr_errclass = 0;
4058 fsp->wbmpx_ptr = wbms;
4061 /* We are returning successfully, set the message type back to
4063 CVAL(outbuf,smb_com) = SMBwriteBmpx;
4065 outsize = set_message(outbuf,1,0,True);
4067 SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
4069 DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
4070 fsp->fnum, numtowrite, nwritten ) );
4072 if (write_through && tcount==nwritten) {
4073 /* we need to send both a primary and a secondary response */
4074 smb_setlen(outbuf,outsize - 4);
4075 send_smb(Client,outbuf);
4077 /* now the secondary */
4078 outsize = set_message(outbuf,1,0,True);
4079 CVAL(outbuf,smb_com) = SMBwritec;
4080 SSVAL(outbuf,smb_vwv0,nwritten);
4087 /****************************************************************************
4088 reply to a SMBwritebs (write block multiplex secondary) request
4089 ****************************************************************************/
4090 int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4093 ssize_t nwritten = -1;
4100 write_bmpx_struct *wbms;
4101 BOOL send_response = False;
4102 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4104 CHECK_FSP(fsp,conn);
4107 tcount = SVAL(inbuf,smb_vwv1);
4108 startpos = IVAL(inbuf,smb_vwv2);
4109 numtowrite = SVAL(inbuf,smb_vwv6);
4110 smb_doff = SVAL(inbuf,smb_vwv7);
4112 data = smb_base(inbuf) + smb_doff;
4114 /* We need to send an SMBwriteC response, not an SMBwritebs */
4115 CVAL(outbuf,smb_com) = SMBwritec;
4117 /* This fd should have an auxiliary struct attached,
4118 check that it does */
4119 wbms = fsp->wbmpx_ptr;
4120 if(!wbms) return(-1);
4122 /* If write through is set we can return errors, else we must
4124 write_through = wbms->wr_mode;
4126 /* Check for an earlier error */
4127 if(wbms->wr_discard)
4128 return -1; /* Just discard the packet */
4130 if(seek_file(fsp,startpos) == -1)
4134 /* We are returning an error - we can delete the aux struct */
4135 if (wbms) free((char *)wbms);
4136 fsp->wbmpx_ptr = NULL;
4137 return(UNIXERROR(ERRDOS,ERRnoaccess));
4139 return(CACHE_ERROR(wbms,ERRDOS,ERRnoaccess));
4142 nwritten = write_file(fsp,data,numtowrite);
4144 if((lp_syncalways(SNUM(conn)) || write_through) &&
4145 lp_strict_sync(SNUM(conn)))
4146 conn->vfs_ops.sync(fsp->fd_ptr->fd);
4148 if (nwritten < (ssize_t)numtowrite)
4152 /* We are returning an error - we can delete the aux struct */
4153 if (wbms) free((char *)wbms);
4154 fsp->wbmpx_ptr = NULL;
4155 return(ERROR(ERRHRD,ERRdiskfull));
4157 return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
4160 /* Increment the total written, if this matches tcount
4161 we can discard the auxiliary struct (hurrah !) and return a writeC */
4162 wbms->wr_total_written += nwritten;
4163 if(wbms->wr_total_written >= tcount)
4167 outsize = set_message(outbuf,1,0,True);
4168 SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
4169 send_response = True;
4173 fsp->wbmpx_ptr = NULL;
4183 /****************************************************************************
4184 reply to a SMBsetattrE
4185 ****************************************************************************/
4186 int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4188 struct utimbuf unix_times;
4190 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4192 outsize = set_message(outbuf,0,0,True);
4194 CHECK_FSP(fsp,conn);
4197 /* Convert the DOS times into unix times. Ignore create
4198 time as UNIX can't set this.
4200 unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
4201 unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
4204 * Patch from Ray Frush <frush@engr.colostate.edu>
4205 * Sometimes times are sent as zero - ignore them.
4208 if ((unix_times.actime == 0) && (unix_times.modtime == 0))
4210 /* Ignore request */
4213 dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
4214 dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
4218 else if ((unix_times.actime != 0) && (unix_times.modtime == 0))
4220 /* set modify time = to access time if modify time was 0 */
4221 unix_times.modtime = unix_times.actime;
4224 /* Set the date on this file */
4225 if(file_utime(conn, fsp->fsp_name, &unix_times))
4226 return(ERROR(ERRDOS,ERRnoaccess));
4228 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
4229 fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
4235 /****************************************************************************
4236 reply to a SMBgetattrE
4237 ****************************************************************************/
4238 int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
4240 SMB_STRUCT_STAT sbuf;
4243 files_struct *fsp = file_fsp(inbuf,smb_vwv0);
4245 outsize = set_message(outbuf,11,0,True);
4247 CHECK_FSP(fsp,conn);
4250 /* Do an fstat on this file */
4251 if(fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd, &sbuf))
4252 return(UNIXERROR(ERRDOS,ERRnoaccess));
4254 mode = dos_mode(conn,fsp->fsp_name,&sbuf);
4256 /* Convert the times into dos times. Set create
4257 date to be last modify date as UNIX doesn't save
4259 put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
4260 put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
4261 put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
4264 SIVAL(outbuf,smb_vwv6,0);
4265 SIVAL(outbuf,smb_vwv8,0);
4269 SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
4270 SIVAL(outbuf,smb_vwv8,SMB_ROUNDUP(sbuf.st_size,1024));
4272 SSVAL(outbuf,smb_vwv10, mode);
4274 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));