static int sendresponse(void *magic, SmbBuffer *, char **errmsgp) { int rv; SmbSession *s = magic; rv = smbresponsesend(s); if (rv < 0) { smbstringprint(errmsgp, "sendresponse failed"); return 0; } return 1; }
SmbProcessResult smbcomecho(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b) { ushort echocount, e; if (!smbcheckwordcount("comecho", h, 1)) return SmbProcessResultFormat; echocount = smbnhgets(pdata); for (e = 0; e < echocount; e++) { ulong bytecountfixupoffset; SmbProcessResult pr; if (!smbbufferputheader(s->response, h, &s->peerinfo) || !smbbufferputs(s->response, e)) return SmbProcessResultMisc; bytecountfixupoffset = smbbufferwriteoffset(s->response); if (!smbbufferputbytes(s->response, smbbufferreadpointer(b), smbbufferreadspace(b)) || !smbbufferfixuprelatives(s->response, bytecountfixupoffset)) return SmbProcessResultMisc; pr = smbresponsesend(s); if (pr != SmbProcessResultOk) return SmbProcessResultDie; } return SmbProcessResultOk; }
int smbsessionwrite(SmbSession *smbs, void *p, int32_t n) { SmbHeader h; SmbOpTableEntry *ote; uint8_t *pdata; int rv; SmbBuffer *b = nil; uint16_t bytecount; SmbProcessResult pr; if (smbs->response == nil) smbs->response = smbbuffernew(576); else smbresponsereset(smbs); smbs->errclass = SUCCESS; smbs->error = SUCCESS; // print("received %ld bytes\n", n); if (n <= 0) goto closedown; b = smbbufferinit(p, p, n); if (!smbbuffergetheader(b, &h, &pdata, &bytecount)) { smblogprint(-1, "smb: invalid header\n"); goto closedown; } smbloglock(); smblogprint(h.command, "received:\n"); smblogdata(h.command, smblogprint, p, n, 0x1000); smblogunlock(); ote = smboptable + h.command; if (ote->name == nil) { smblogprint(-1, "smb: illegal opcode 0x%.2x\n", h.command); goto unimp; } if (ote->process == nil) { smblogprint(-1, "smb: opcode %s unimplemented\n", ote->name); goto unimp; } if (smbs->nextcommand != SMB_COM_NO_ANDX_COMMAND && smbs->nextcommand != h.command) { smblogprint(-1, "smb: wrong command - expected %.2x\n", smbs->nextcommand); goto misc; } smbs->nextcommand = SMB_COM_NO_ANDX_COMMAND; switch (h.command) { case SMB_COM_NEGOTIATE: case SMB_COM_SESSION_SETUP_ANDX: case SMB_COM_TREE_CONNECT_ANDX: case SMB_COM_ECHO: break; default: if (smbs->state != SmbSessionEstablished) { smblogprint(-1, "aquarela: command %.2x unexpected\n", h.command); goto unimp; } } pr = (*ote->process)(smbs, &h, pdata, b); switch (pr) { case SmbProcessResultUnimp: unimp: smbseterror(smbs, ERRDOS, ERRunsup); pr = SmbProcessResultError; break; case SmbProcessResultFormat: smbseterror(smbs, ERRSRV, ERRsmbcmd); pr = SmbProcessResultError; break; case SmbProcessResultMisc: misc: smbseterror(smbs, ERRSRV, ERRerror); pr = SmbProcessResultError; break; case SmbProcessResultOk: case SmbProcessResultError: case SmbProcessResultReply: case SmbProcessResultDie: break; } if (pr == SmbProcessResultError) { smblogprint(h.command, "reply: error %d/%d\n", smbs->errclass, smbs->error); if (!smbresponseputerror(smbs, &h, smbs->errclass, smbs->error)) pr = SmbProcessResultDie; else pr = SmbProcessResultReply; } else smblogprint(h.command, "reply: ok\n"); if (pr == SmbProcessResultReply) rv = smbresponsesend(smbs) == SmbProcessResultOk ? 0 : -1; else if (pr == SmbProcessResultDie) rv = -1; else rv = 0; goto done; closedown: rv = -1; done: if (rv < 0) { smblogprintif(smbglobals.log.sessions, "shutting down\n"); smbsessionfree(smbs); } smbbufferfree(&b); if (smbglobals.log.poolparanoia) poolcheck(mainmem); return rv; }