#include "headers.h" static SmbTransactionMethod smbtransactionmethodrap = { .encodeprimary = smbtransactionencodeprimary, .sendrequest = smbtransactionclientsend, .receiveresponse = smbtransactionclientreceive, .decoderesponse = smbtransactiondecoderesponse, }; int smbclientrap(SmbClient *c, SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata, char **errmsgp) { SmbTransaction transaction; SmbHeader h; memset(&transaction, 0, sizeof(transaction)); transaction.in.name = smbglobals.pipelanman; transaction.in.parameters = smbbufferreadpointer(inparam); transaction.in.tpcount = smbbufferreadspace(inparam); transaction.in.maxpcount = smbbufferwritespace(outparam); transaction.in.maxdcount = smbbufferwritespace(outdata); transaction.out.parameters = outparam; transaction.out.data = outdata; h = c->protoh; h.tid = c->ipctid; h.mid = 0; return smbtransactionexecute(&transaction, &h, &c->peerinfo, c->b, &smbtransactionmethodrap, c, nil, errmsgp); } int smbnetserverenum2(SmbClient *c, ulong stype, char *domain, int *entriesp, SmbRapServerInfo1 **sip, char **errmsgp) { int rv; ushort ec, entries, total, converter; SmbRapServerInfo1 *si = nil; SmbBuffer *ipb = smbbuffernew(512); SmbBuffer *odb = smbbuffernew(65535); SmbBuffer *opb = smbbuffernew(8); smbbufferputs(ipb, 104); smbbufferputstring(ipb, nil, SMB_STRING_ASCII, "WrLehDz"); smbbufferputstring(ipb, nil, SMB_STRING_ASCII, "B16BBDz"); smbbufferputs(ipb, 1); smbbufferputs(ipb, smbbufferwritespace(odb)); smbbufferputl(ipb, stype); smbbufferputstring(ipb, nil, SMB_STRING_ASCII, domain); rv = !smbclientrap(c, ipb, opb, odb, errmsgp); smbbufferfree(&ipb); if (rv == 0) { char *remark, *eremark; int remarkspace; int i; if (!smbbuffergets(opb, &ec) || !smbbuffergets(opb, &converter) || !smbbuffergets(opb, &entries) || !smbbuffergets(opb, &total)) { smbstringprint(errmsgp, "smbnetserverenum2: not enough return parameters"); rv = -1; goto done; } if (ec != 0) { rv = ec; goto done; } if (smbbufferreadspace(odb) < entries * 26) { smbstringprint(errmsgp, "smbnetserverenum2: not enough return data"); rv = -1; goto done; } remarkspace = smbbufferreadspace(odb) - entries * 26; si = smbemalloc(entries * sizeof(SmbRapServerInfo1) + remarkspace); remark = (char *)&si[entries]; eremark = remark + remarkspace; for (i = 0; i < entries; i++) { ulong offset; int remarklen; assert(smbbuffergetbytes(odb, si[i].name, 16)); assert(smbbuffergetb(odb, &si[i].vmaj)); assert(smbbuffergetb(odb, &si[i].vmin)); assert(smbbuffergetl(odb, &si[i].type)); assert(smbbuffergetl(odb, &offset)); offset -= converter; if (!smbbufferoffsetcopystr(odb, offset, remark, eremark - remark, &remarklen)) { smbstringprint(errmsgp, "smbnetserverenum2: invalid string offset"); rv = -1; goto done; } si[i].remark = remark; remark += remarklen; } *sip = si; si = nil; *entriesp = entries; } else rv = -1; done: free(si); smbbufferfree(&opb); smbbufferfree(&odb); return rv; }