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 smbclientopen(SmbClient *c, uint16_t mode, char *name, uint8_t *errclassp, uint16_t *errorp, uint16_t *fidp, uint16_t *attrp, uint32_t *mtimep, uint32_t *sizep, uint16_t *accessallowedp, char **errmsgp) { SmbBuffer *b; SmbHeader h; uint32_t bytecountfixup; int32_t n; uint8_t *pdata; uint16_t bytecount; b = smbbuffernew(65535); h = c->protoh; h.tid = c->sharetid; h.command = SMB_COM_OPEN; h.wordcount = 2; smbbufferputheader(b, &h, &c->peerinfo); smbbufferputs(b, mode); smbbufferputs(b, 0); bytecountfixup = smbbufferwriteoffset(b); smbbufferputs(b, 0); smbbufferputb(b, 4); smbbufferputstring(b, &c->peerinfo, SMB_STRING_REVPATH, name); smbbufferfixuprelatives(b, bytecountfixup); nbsswrite(c->nbss, smbbufferreadpointer(b), smbbufferwriteoffset(b)); smbbufferreset(b); n = nbssread(c->nbss, smbbufferwritepointer(b), smbbufferwritespace(b)); if (n < 0) { smbstringprint(errmsgp, "read error: %r"); smbbufferfree(&b); return 0; } smbbuffersetreadlen(b, n); if (!smbbuffergetandcheckheader(b, &h, h.command, 7, &pdata, &bytecount, errmsgp)) { smbbufferfree(&b); return 0; } if (h.errclass) { *errclassp = h.errclass; *errorp = h.error; smbbufferfree(&b); return 0; } *fidp = smbnhgets(pdata); pdata += 2; *attrp = smbnhgets(pdata); pdata += 2; *mtimep = smbnhgetl(pdata); pdata += 4; *sizep = smbnhgets(pdata); pdata += 4; *accessallowedp = smbnhgets(pdata); return 1; }
void smbbuffersetbuf(SmbBuffer *s, void *p, ulong maxlen) { s->realmaxlen = s->maxlen = maxlen; if (s->buf) { if (s->flags & BUFFER) free(s->buf); s->buf = nil; } s->flags &= ~BUFFER; if (p) s->buf = p; else { s->buf = smbemalloc(maxlen); s->flags |= BUFFER; } smbbufferreset(s); }
void smbresponsereset(SmbSession *s) { smbbufferreset(s->response); }
int smbtransactionexecute(SmbTransaction *t, SmbHeader *h, SmbPeerInfo *p, SmbBuffer *iob, SmbTransactionMethod *method, void *magic, SmbHeader *rhp, char **errmsgp) { uint8_t sentwordcount; uint16_t sentbytecount; SmbHeader rh; smbbufferreset(iob); if (!(*method->encodeprimary)(t, h, p, iob, &sentwordcount, &sentbytecount, errmsgp)) return 0; // smblogprint(-1, "sent...\n"); // smblogdata(-1, smblogprint, smbbufferreadpointer(iob), smbbufferreadspace(iob)); if (!(*method->sendrequest)(magic, iob, errmsgp)) return 0; if (t->in.pcount < t->in.tpcount || t->in.dcount < t->in.tdcount) { uint8_t wordcount; uint16_t bytecount; /* secondary needed */ if (method->encodesecondary == nil || method->receiveintermediate == nil) { smbstringprint(errmsgp, "buffer too small and secondaries not allowed"); return 0; } if (!(*method->receiveintermediate)(magic, &wordcount, &bytecount, errmsgp)) return 0; if (sentwordcount != wordcount || sentbytecount != bytecount) { smbstringprint(errmsgp, "server intermediate reply counts differ"); return 0; } do { if (!(*method->encodesecondary)(t, h, iob, errmsgp)) return 0; if (!(*method->sendrequest)(magic, iob, errmsgp)) return 0; } while (t->in.pcount < t->in.tpcount || t->in.dcount < t->in.tdcount); } if (method->receiveresponse == nil || method->decoderesponse == nil) return 1; do { uint8_t *pdata; uint16_t bytecount; if (!(*method->receiveresponse)(magic, iob, errmsgp)) return 0; if (!smbbuffergetheader(iob, &rh, &pdata, &bytecount)) { smbstringprint(errmsgp, "smbtransactionexecute: invalid response header"); return 0; } if (!smbcheckheaderdirection(&rh, 1, errmsgp)) return 0; if (rh.errclass != SUCCESS) { smbstringprint(errmsgp, "smbtransactionexecute: remote error %d/%d", rh.errclass, rh.error); return 0; } if (!smbbuffertrimreadlen(iob, bytecount)) { smbstringprint(errmsgp, "smbtransactionexecute: invalid bytecount"); return 0; } // smblogprint(-1, "received...\n"); // smblogdata(-1, smblogprint, smbbufferreadpointer(iob), smbbufferreadspace(iob)); if (!(*method->decoderesponse)(t, &rh, pdata, iob, errmsgp)) return 0; } while (smbbufferwriteoffset(t->out.parameters) < t->out.tpcount || smbbufferwriteoffset(t->out.data) < t->out.tdcount); if (rhp) *rhp = rh; return 1; }