summaryrefslogtreecommitdiff
path: root/source/smbd/reply.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/reply.c')
-rw-r--r--source/smbd/reply.c177
1 files changed, 57 insertions, 120 deletions
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index b7b51775bb8..a84a9af0c17 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -25,13 +25,11 @@
#include "includes.h"
-#include "loadparm.h"
#include "trans2.h"
/* look in server.c for some explanation of these variables */
extern int Protocol;
extern int DEBUGLEVEL;
-extern int chain_size;
extern int maxxmit;
extern int chain_fnum;
extern char magic_char;
@@ -179,11 +177,8 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
pstring password;
pstring devicename;
int connection_num;
- int outsize = 0;
int uid = SVAL(inbuf,smb_uid);
int vuid;
- int smb_com2 = SVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
int passlen = SVAL(inbuf,smb_vwv3);
*service = *user = *password = *devicename = 0;
@@ -222,7 +217,7 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
if (connection_num < 0)
return(connection_error(inbuf,outbuf,connection_num));
- outsize = set_message(outbuf,2,strlen(devicename)+1,True);
+ set_message(outbuf,2,strlen(devicename)+1,True);
DEBUG(3,("%s tconX service=%s user=%s cnum=%d\n",timestring(),service,user,connection_num));
@@ -230,17 +225,9 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
SSVAL(inbuf,smb_tid,connection_num);
SSVAL(outbuf,smb_tid,connection_num);
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(chain_size + outsize)-4);
-
strcpy(smb_buf(outbuf),devicename);
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -279,11 +266,8 @@ reply to a session setup command
****************************************************************************/
int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
- int outsize = 0;
int sess_uid;
int gid;
- int smb_com2;
- int smb_off2;
int smb_bufsize;
int smb_mpxmax;
int smb_vc_num;
@@ -295,12 +279,11 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
BOOL valid_nt_password = False;
pstring user;
BOOL guest=False;
+ BOOL computer_id=False;
*smb_apasswd = 0;
sess_uid = SVAL(inbuf,smb_uid);
- smb_com2 = CVAL(inbuf,smb_vwv0);
- smb_off2 = SVAL(inbuf,smb_vwv1);
smb_bufsize = SVAL(inbuf,smb_vwv2);
smb_mpxmax = SVAL(inbuf,smb_vwv3);
smb_vc_num = SVAL(inbuf,smb_vwv4);
@@ -334,11 +317,13 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
StrnCpy(smb_apasswd,p + passlen1,smb_apasslen);
}
}
+#if NT_WORKAROUND
if (passlen2 == 1) {
/* apparently NT sometimes sets passlen2 to 1 when it means 0. This
tries to work around that problem */
passlen2 = 0;
}
+#endif
p += passlen1 + passlen2;
strcpy(user,p); p = skip_string(p,1);
DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n",
@@ -348,6 +333,15 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
DEBUG(3,("sesssetupX:name=[%s]\n",user));
+ /* If name ends in $ then I think it's asking about whether a */
+ /* computer with that name (minus the $) has access. For now */
+ /* say yes to everything ending in $. */
+ if (user[strlen(user) - 1] == '$') {
+ computer_id = True;
+ user[strlen(user) - 1] = '\0';
+ }
+
+
if (!*user)
strcpy(user,lp_guestaccount(-1));
@@ -379,7 +373,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
}
if (!valid_nt_password && !guest && !password_ok(user,smb_apasswd,smb_apasslen,NULL,False))
{
- if (lp_security() >= SEC_USER) {
+ if (!computer_id && lp_security() >= SEC_USER) {
#if (GUEST_SESSSETUP == 0)
return(ERROR(ERRSRV,ERRbadpw));
#endif
@@ -413,15 +407,15 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
/* it's ok - setup a reply */
if (Protocol < PROTOCOL_NT1) {
- outsize = set_message(outbuf,3,0,True);
+ set_message(outbuf,3,0,True);
} else {
char *p;
- outsize = set_message(outbuf,3,3,True);
+ set_message(outbuf,3,3,True);
p = smb_buf(outbuf);
strcpy(p,"Unix"); p = skip_string(p,1);
strcpy(p,"Samba "); strcat(p,VERSION); p = skip_string(p,1);
- strcpy(p,my_workgroup()); p = skip_string(p,1);
- outsize = set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
+ strcpy(p,lp_workgroup()); p = skip_string(p,1);
+ set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
/* perhaps grab OS version here?? */
}
@@ -440,10 +434,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
SSVAL(inbuf,smb_uid,(uint16)pw->pw_uid);
}
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
-
- if (guest)
+ if (guest && !computer_id)
SSVAL(outbuf,smb_vwv2,1);
/* register the name and uid as being validated, so further connections
@@ -452,12 +443,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
maxxmit = MIN(maxxmit,smb_bufsize);
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -962,10 +948,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
pstring fname;
int cnum = SVAL(inbuf,smb_tid);
int fnum = -1;
- int outsize = 0;
int openmode = 0;
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
int smb_mode = SVAL(inbuf,smb_vwv3);
int smb_attr = SVAL(inbuf,smb_vwv5);
#if 0
@@ -979,6 +962,10 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
struct stat sbuf;
int smb_action = 0;
+ /* If it's an IPC, pass off the pipe handler. */
+ if (IS_IPC(cnum))
+ return reply_open_pipe_and_X(inbuf,outbuf,length,bufsize);
+
/* XXXX we need to handle passed times, sattr and flags */
strcpy(fname,smb_buf(inbuf));
@@ -1018,9 +1005,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
return(ERROR(ERRDOS,ERRnoaccess));
}
- outsize = set_message(outbuf,15,0,True);
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
+ set_message(outbuf,15,0,True);
SSVAL(outbuf,smb_vwv2,fnum);
SSVAL(outbuf,smb_vwv3,fmode);
put_dos_date3(outbuf,smb_vwv4,mtime);
@@ -1030,14 +1015,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
chain_fnum = fnum;
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- chain_fnum = -1;
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -1046,26 +1024,15 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
****************************************************************************/
int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize)
{
- int outsize = 0;
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
int uid = SVAL(inbuf,smb_uid);
invalidate_uid(uid);
- outsize = set_message(outbuf,2,0,True);
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
+ set_message(outbuf,2,0,True);
DEBUG(3,("%s ulogoffX uid=%d\n",timestring(),uid));
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -1179,7 +1146,9 @@ static BOOL can_delete(char *fname,int cnum,int dirtype)
if (sys_lstat(fname,&sbuf) != 0) return(False);
fmode = dos_mode(cnum,fname,&sbuf);
if (fmode & aDIR) return(False);
- if (fmode & aRONLY) return(False);
+ if (!lp_delete_readonly(SNUM(cnum))) {
+ if (fmode & aRONLY) return(False);
+ }
if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
return(False);
if (!check_file_sharing(cnum,fname)) return(False);
@@ -1360,7 +1329,7 @@ int reply_readbraw(char *inbuf, char *outbuf)
fname,startpos,nread,ret));
#else
- ret = read_file(fnum,header+4,startpos,nread,nread,-1,False);
+ ret = read_file(fnum,header+4,startpos,nread);
if (ret < mincount) ret = 0;
_smb_setlen(header,ret);
@@ -1402,7 +1371,7 @@ int reply_lockread(char *inbuf,char *outbuf)
if(!do_lock( fnum, cnum, numtoread, startpos, &eclass, &ecode))
return (ERROR(eclass,ecode));
- nread = read_file(fnum,data,startpos,numtoread,numtoread,-1,False);
+ nread = read_file(fnum,data,startpos,numtoread);
if (nread < 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -1447,7 +1416,7 @@ int reply_read(char *inbuf,char *outbuf)
return(ERROR(ERRDOS,ERRlock));
if (numtoread > 0)
- nread = read_file(fnum,data,startpos,numtoread,numtoread,-1,False);
+ nread = read_file(fnum,data,startpos,numtoread);
if (nread < 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -1469,8 +1438,6 @@ int reply_read(char *inbuf,char *outbuf)
****************************************************************************/
int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
int fnum = GETFNUM(inbuf,smb_vwv2);
uint32 smb_offs = IVAL(inbuf,smb_vwv3);
int smb_maxcnt = SVAL(inbuf,smb_vwv5);
@@ -1478,7 +1445,6 @@ int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
int cnum;
int nread = -1;
char *data;
- int outsize = 0;
BOOL ok = False;
cnum = SVAL(inbuf,smb_tid);
@@ -1487,38 +1453,28 @@ int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
CHECK_READ(fnum);
CHECK_ERROR(fnum);
- outsize = set_message(outbuf,12,0,True);
+ set_message(outbuf,12,0,True);
data = smb_buf(outbuf);
if (is_locked(fnum,cnum,smb_maxcnt,smb_offs))
return(ERROR(ERRDOS,ERRlock));
- nread = read_file(fnum,data,smb_offs,smb_maxcnt,smb_maxcnt,-1,False);
+ nread = read_file(fnum,data,smb_offs,smb_maxcnt);
ok = True;
if (nread < 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
- outsize += nread;
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(outsize+chain_size)-4);
SSVAL(outbuf,smb_vwv5,nread);
- SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf) + chain_size);
+ SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
SSVAL(smb_buf(outbuf),-2,nread);
- DEBUG(3,("%s readX fnum=%d cnum=%d min=%d max=%d nread=%d com2=%d off2=%d\n",
+ DEBUG(3,("%s readX fnum=%d cnum=%d min=%d max=%d nread=%d\n",
timestring(),fnum,cnum,
- smb_mincnt,smb_maxcnt,nread,smb_com2,smb_off2));
+ smb_mincnt,smb_maxcnt,nread));
chain_fnum = fnum;
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- chain_fnum = -1;
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -1587,7 +1543,7 @@ int reply_writebraw(char *inbuf,char *outbuf)
send_smb(Client,outbuf);
/* Now read the raw data into the buffer and write it */
- if(read_smb_length(Client,inbuf,0) == -1) {
+ if (read_smb_length(Client,inbuf,SMB_SECONDARY_WAIT) == -1) {
exit_server("secondary writebraw failed");
}
@@ -1750,8 +1706,6 @@ int reply_write(char *inbuf,char *outbuf,int dum1,int dum2)
****************************************************************************/
int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
int fnum = GETFNUM(inbuf,smb_vwv2);
uint32 smb_offs = IVAL(inbuf,smb_vwv3);
int smb_dsize = SVAL(inbuf,smb_vwv10);
@@ -1759,7 +1713,6 @@ int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
int cnum;
int nwritten = -1;
- int outsize = 0;
char *data;
cnum = SVAL(inbuf,smb_tid);
@@ -1787,10 +1740,8 @@ int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
if(((nwritten == 0) && (smb_dsize != 0))||(nwritten < 0))
return(UNIXERROR(ERRDOS,ERRnoaccess));
- outsize = set_message(outbuf,6,0,True);
+ set_message(outbuf,6,0,True);
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(outsize+chain_size)-4);
SSVAL(outbuf,smb_vwv2,nwritten);
if (nwritten < smb_dsize) {
@@ -1805,14 +1756,7 @@ int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
if (lp_syncalways(SNUM(cnum)) || write_through)
sync_file(fnum);
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- chain_fnum = -1;
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -1924,11 +1868,11 @@ int reply_close(char *inbuf,char *outbuf)
mtime = make_unix_date3(inbuf+smb_vwv1);
- close_file(fnum);
-
/* try and set the date */
set_filetime(Files[fnum].name,mtime);
+ close_file(fnum);
+
/* We have a cached error */
if(eclass || err)
return(ERROR(eclass,err));
@@ -1972,10 +1916,10 @@ int reply_writeclose(char *inbuf,char *outbuf)
nwritten = write_file(fnum,data,numtowrite);
- close_file(fnum);
-
set_filetime(Files[fnum].name,mtime);
+ close_file(fnum);
+
DEBUG(3,("%s writeclose fnum=%d cnum=%d num=%d wrote=%d (numopen=%d)\n",
timestring(),fnum,cnum,numtowrite,nwritten,
Connections[cnum].num_files_open));
@@ -2059,6 +2003,11 @@ int reply_tdis(char *inbuf,char *outbuf)
cnum = SVAL(inbuf,smb_tid);
uid = SVAL(inbuf,smb_uid);
+ if (!OPEN_CNUM(cnum)) {
+ DEBUG(4,("Invalid cnum in tdis (%d)\n",cnum));
+ return(ERROR(ERRSRV,ERRinvnid));
+ }
+
Connections[cnum].used = False;
close_cnum(cnum,uid);
@@ -2806,8 +2755,6 @@ int reply_setdir(char *inbuf,char *outbuf)
****************************************************************************/
int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
{
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
int fnum = GETFNUM(inbuf,smb_vwv2);
uint16 locktype = SVAL(inbuf,smb_vwv3);
uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
@@ -2818,7 +2765,7 @@ int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
int i;
char *data;
uint32 ecode=0, dummy2;
- int outsize, eclass=0, dummy1;
+ int eclass=0, dummy1;
cnum = SVAL(inbuf,smb_tid);
@@ -2857,24 +2804,14 @@ int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
return ERROR(eclass,ecode);
}
- outsize = set_message(outbuf,2,0,True);
-
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(outsize+chain_size)-4);
+ set_message(outbuf,2,0,True);
DEBUG(3,("%s lockingX fnum=%d cnum=%d type=%d num_locks=%d num_ulocks=%d\n",
timestring(),fnum,cnum,locktype,num_locks,num_ulocks));
chain_fnum = fnum;
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- chain_fnum = -1;
-
- return(outsize);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -2926,7 +2863,7 @@ int reply_readbmpx(char *inbuf,char *outbuf,int length,int bufsize)
{
int N = MIN(max_per_packet,tcount-total_read);
- nread = read_file(fnum,data,startpos,N,N,-1,False);
+ nread = read_file(fnum,data,startpos,N);
if (nread <= 0) nread = 0;