SmbProcessResult smbresponsesend(SmbSession *s) { uchar cmd; SmbProcessResult pr; assert(smbbufferoffsetgetb(s->response, 4, &cmd)); smbloglock(); smblogprint(cmd, "sending:\n"); smblogdata(cmd, smblogprint, smbbufferreadpointer(s->response), smbbufferreadspace(s->response), 256); smblogunlock(); if (s->nbss) { NbScatterGather a[2]; a[0].p = smbbufferreadpointer(s->response); a[0].l = smbbufferreadspace(s->response); a[1].p = nil; nbssgatherwrite(s->nbss, a); pr = SmbProcessResultOk; } else if (s->cifss) { ulong l = smbbufferreadspace(s->response); uchar nl[4]; hnputl(nl, l); write(s->cifss->fd, nl, 4); write(s->cifss->fd, smbbufferreadpointer(s->response), l); pr = SmbProcessResultOk; } else pr = SmbProcessResultDie; smbbufferreset(s->response); return pr; }
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; }
int smbclienttrans2findfirst2(SmbClient *c, ushort searchcount, char *filename, ushort *sidp, ushort *searchcountp, ushort *endofsearchp,SmbFindFileBothDirectoryInfo *ip, char **errmsgp) { int rv; ushort setup; SmbBuffer *inparam; SmbBuffer *outparam; SmbBuffer *outdata; SmbHeader rh; setup = SMB_TRANS2_FIND_FIRST2; inparam = smbbuffernew(512); smbbufferputs(inparam, 0x16); smbbufferputs(inparam, searchcount); smbbufferputs(inparam, 7); smbbufferputs(inparam, SMB_FIND_FILE_BOTH_DIRECTORY_INFO); smbbufferputl(inparam, 0); smbbufferputstring(inparam, &c->peerinfo, 0, filename); outparam = smbbuffernew(10); outdata = smbbuffernew(65535); rv = smbclienttrans2(c, 1, &setup, inparam, outparam, outdata, &rh, errmsgp); smbbufferfree(&inparam); if (rv) { ushort eaerroroffset, lastnameoffset; ulong nextentry; int i; if (!smbbuffergets(outparam, sidp) || !smbbuffergets(outparam, searchcountp) || !smbbuffergets(outparam, endofsearchp) || !smbbuffergets(outparam, &eaerroroffset) || !smbbuffergets(outparam, &lastnameoffset)) { smbstringprint(errmsgp, "smbclienttrans2findfirst2: not enough parameters returned"); rv = 0; goto done; } nextentry = 0; smblogprint(-1, "returned data:\n"); smblogdata(-1, smblogprint, smbbufferreadpointer(outdata), smbbufferreadspace(outdata), 256); for (i = 0; i < *searchcountp; i++) { SmbFindFileBothDirectoryInfo *info = ip + i; ulong neo, filenamelength, easize; uchar shortnamelength; if (i && !smbbufferreadskipto(outdata, nextentry)) { underflow: smbstringprint(errmsgp, "smbclientrans2findfirst2: not enough data returned"); rv = 0; goto done; } if (!smbbuffergetl(outdata, &neo)) goto underflow; nextentry = smbbufferreadoffset(outdata) + neo - 4; print("neo 0x%.8lux\n", neo); if (!smbbuffergetl(outdata, &info->fileindex) || !smbbuffergetv(outdata, &info->creationtime) || !smbbuffergetv(outdata, &info->lastaccesstime) || !smbbuffergetv(outdata, &info->lastwritetime) || !smbbuffergetv(outdata, &info->changetime) || !smbbuffergetv(outdata, &info->endoffile) || !smbbuffergetv(outdata, &info->allocationsize)) goto underflow; print("got here\n"); if (!smbbuffergetl(outdata, &info->extfileattributes) || !smbbuffergetl(outdata, &filenamelength) || !smbbuffergetl(outdata, &easize) || !smbbuffergetb(outdata, &shortnamelength) || !smbbuffergetbytes(outdata, nil, 1) || !smbbuffergetbytes(outdata, nil, 24) || !smbbuffergetstring(outdata, &rh, SMB_STRING_REVPATH, &info->filename)) goto underflow; print("got here as well\n"); } } done: smbbufferfree(&outparam); smbbufferfree(&outdata); return rv; }