diff options
Diffstat (limited to 'source/smbd/reply.c')
-rw-r--r-- | source/smbd/reply.c | 177 |
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; |