/* * Wait for reply on the request */ static int smb_rq_reply(struct smb_rq *rqp) { struct mdchain *mdp = &rqp->sr_rp; u_int32_t tdw; u_int8_t tb; int error, rperror = 0; error = smb_iod_waitrq(rqp); if (error) return error; error = md_get_uint32(mdp, &tdw); if (error) return error; error = md_get_uint8(mdp, &tb); if (rqp->sr_vc->vc_hflags2 & SMB_FLAGS2_ERR_STATUS) { error = md_get_uint32le(mdp, &rqp->sr_error); } else { error = md_get_uint8(mdp, &rqp->sr_errclass); error = md_get_uint8(mdp, &tb); error = md_get_uint16le(mdp, &rqp->sr_serror); if (!error) rperror = smb_maperror(rqp->sr_errclass, rqp->sr_serror); } error = md_get_uint8(mdp, &rqp->sr_rpflags); error = md_get_uint16le(mdp, &rqp->sr_rpflags2); error = md_get_uint32(mdp, &tdw); error = md_get_uint32(mdp, &tdw); error = md_get_uint32(mdp, &tdw); error = md_get_uint16le(mdp, &rqp->sr_rptid); error = md_get_uint16le(mdp, &rqp->sr_rppid); error = md_get_uint16le(mdp, &rqp->sr_rpuid); error = md_get_uint16le(mdp, &rqp->sr_rpmid); if (error == 0 && (rqp->sr_vc->vc_hflags2 & SMB_FLAGS2_SECURITY_SIGNATURE)) error = smb_rq_verify(rqp); SMBSDEBUG("M:%04x, P:%04x, U:%04x, T:%04x, E: %d:%d\n", rqp->sr_rpmid, rqp->sr_rppid, rqp->sr_rpuid, rqp->sr_rptid, rqp->sr_errclass, rqp->sr_serror); return error ? error : rperror; }
/* * Wait for reply on the request */ static int smb_rq_reply(struct smb_rq *rqp) { struct mdchain *mdp = &rqp->sr_rp; u_int8_t tb; int error, rperror = 0; if (rqp->sr_timo == SMBNOREPLYWAIT) return (smb_iod_removerq(rqp)); error = smb_iod_waitrq(rqp); if (error) return (error); /* * If the request was signed, validate the * signature on the response. */ if (rqp->sr_rqflags2 & SMB_FLAGS2_SECURITY_SIGNATURE) { error = smb_rq_verify(rqp); if (error) return (error); } /* * Parse the SMB header */ error = md_get_uint32le(mdp, NULL); if (error) return (error); error = md_get_uint8(mdp, &tb); error = md_get_uint32le(mdp, &rqp->sr_error); error = md_get_uint8(mdp, &rqp->sr_rpflags); error = md_get_uint16le(mdp, &rqp->sr_rpflags2); if (rqp->sr_rpflags2 & SMB_FLAGS2_ERR_STATUS) { /* * Do a special check for STATUS_BUFFER_OVERFLOW; * it's not an error. */ if (rqp->sr_error == NT_STATUS_BUFFER_OVERFLOW) { /* * Don't report it as an error to our caller; * they can look at rqp->sr_error if they * need to know whether we got a * STATUS_BUFFER_OVERFLOW. * XXX - should we do that for all errors * where (error & 0xC0000000) is 0x80000000, * i.e. all warnings? */ rperror = 0; } else rperror = smb_maperr32(rqp->sr_error); } else { rqp->sr_errclass = rqp->sr_error & 0xff; rqp->sr_serror = rqp->sr_error >> 16; rperror = smb_maperror(rqp->sr_errclass, rqp->sr_serror); } if (rperror == EMOREDATA) { rperror = E2BIG; rqp->sr_flags |= SMBR_MOREDATA; } else rqp->sr_flags &= ~SMBR_MOREDATA; error = md_get_uint32le(mdp, NULL); error = md_get_uint32le(mdp, NULL); error = md_get_uint32le(mdp, NULL); error = md_get_uint16le(mdp, &rqp->sr_rptid); error = md_get_uint16le(mdp, &rqp->sr_rppid); error = md_get_uint16le(mdp, &rqp->sr_rpuid); error = md_get_uint16le(mdp, &rqp->sr_rpmid); SMBSDEBUG("M:%04x, P:%04x, U:%04x, T:%04x, E: %d:%d\n", rqp->sr_rpmid, rqp->sr_rppid, rqp->sr_rpuid, rqp->sr_rptid, rqp->sr_errclass, rqp->sr_serror); return ((error) ? error : rperror); }