smbtransaction.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. #include "headers.h"
  2. typedef struct Args Args;
  3. struct Args {
  4. ulong pcount;
  5. ulong poffset;
  6. ulong pdisplacement;
  7. ulong dcount;
  8. ulong doffset;
  9. ulong ddisplacement;
  10. uchar scount;
  11. };
  12. int
  13. _smbtransactiondecodeprimary(SmbTransaction *t, SmbHeader *h, uchar *pdata, SmbBuffer *b, int hasname, char **errmsgp)
  14. {
  15. ushort poffset, doffset;
  16. if (h->wordcount < 14) {
  17. smbstringprint(errmsgp, "word count less than 14");
  18. return -1;
  19. }
  20. t->in.scount = pdata[13 * 2];
  21. if (h->wordcount != 14 + t->in.scount) {
  22. smbstringprint(errmsgp, "smbcomtransaction: word count invalid\n");
  23. return -1;
  24. }
  25. t->in.tpcount = smbnhgets(pdata); pdata += 2;
  26. t->in.tdcount = smbnhgets(pdata); pdata += 2;
  27. t->in.maxpcount = smbnhgets(pdata); pdata += 2;
  28. t->in.maxdcount = smbnhgets(pdata); pdata += 2;
  29. t->in.maxscount = *pdata++;
  30. pdata++;
  31. t->in.flags = smbnhgets(pdata); pdata += 2;
  32. pdata += 4; /* timeout */
  33. pdata += 2;
  34. t->in.pcount = smbnhgets(pdata); pdata += 2;
  35. poffset = smbnhgets(pdata); pdata += 2;
  36. t->in.dcount = smbnhgets(pdata); pdata += 2;
  37. doffset = smbnhgets(pdata); pdata += 2;
  38. pdata++; /* scount */
  39. pdata++; /* reserved */
  40. smbfree(&t->in.setup);
  41. if (t->in.scount) {
  42. int x;
  43. t->in.setup = smbemalloc(t->in.scount * sizeof(ushort));
  44. for (x = 0; x < t->in.scount; x++) {
  45. t->in.setup[x] = smbnhgets(pdata);
  46. pdata += 2;
  47. }
  48. }
  49. smbfree(&t->in.name);
  50. if (hasname && !smbbuffergetstring(b, h, SMB_STRING_PATH, &t->in.name)) {
  51. smbstringprint(errmsgp, "not enough bdata for name");
  52. return -1;
  53. }
  54. if (poffset + t->in.pcount > smbbufferwriteoffset(b)) {
  55. smbstringprint(errmsgp, "not enough bdata for parameters");
  56. return -1;
  57. }
  58. if (t->in.pcount > t->in.tpcount) {
  59. smbstringprint(errmsgp, "too many parameters");
  60. return -1;
  61. }
  62. smbfree(&t->in.parameters);
  63. t->in.parameters = smbemalloc(t->in.tpcount);
  64. memcpy(t->in.parameters, smbbufferpointer(b, poffset), t->in.pcount);
  65. if (doffset + t->in.dcount > smbbufferwriteoffset(b)) {
  66. smbstringprint(errmsgp, "not enough bdata for data");
  67. return -1;
  68. }
  69. if (t->in.dcount > t->in.tdcount) {
  70. smbstringprint(errmsgp, "too much data");
  71. return -1;
  72. }
  73. smbfree(&t->in.data);
  74. t->in.data = smbemalloc(t->in.tdcount);
  75. memcpy(t->in.data, smbbufferpointer(b, doffset), t->in.dcount);
  76. if (t->in.dcount < t->in.tdcount || t->in.pcount < t->in.tpcount)
  77. return 0;
  78. return 1;
  79. }
  80. int
  81. decoderesponse(SmbTransaction *t, Args *a, SmbBuffer *b, char **errmsgp)
  82. {
  83. if (t->out.tpcount > smbbufferwritemaxoffset(t->out.parameters)) {
  84. smbstringprint(errmsgp, "decoderesponse: too many parameters for buffer");
  85. return 0;
  86. }
  87. if (t->out.tdcount > smbbufferwritemaxoffset(t->out.data)) {
  88. smbstringprint(errmsgp, "decoderesponse: too much data for buffer");
  89. return 0;
  90. }
  91. if (a->pdisplacement + a->pcount > t->out.tpcount) {
  92. smbstringprint(errmsgp, "decoderesponse: more parameters than tpcount");
  93. return 0;
  94. }
  95. if (a->pdisplacement != smbbufferwriteoffset(t->out.parameters)) {
  96. smbstringprint(errmsgp, "decoderesponse: parameter displacement inconsistent");
  97. return 0;
  98. }
  99. if (a->ddisplacement + a->dcount > t->out.tdcount) {
  100. smbstringprint(errmsgp, "decoderesponse: more data than tdcount");
  101. return 0;
  102. }
  103. if (a->ddisplacement != smbbufferwriteoffset(t->out.data)) {
  104. smbstringprint(errmsgp, "decoderesponse: data displacement inconsistent");
  105. return 0;
  106. }
  107. assert(a->scount == 0);
  108. if (a->pcount) {
  109. if (!smbbufferreadskipto(b, a->poffset)) {
  110. smbstringprint(errmsgp, "smbtransactiondecoderesponse: invalid parameter offset");
  111. return 0;
  112. }
  113. if (!smbbuffercopy(t->out.parameters, b, a->pcount)) {
  114. smbstringprint(errmsgp, "smbtransactiondecoderesponse: not enough data for parameters");
  115. return 0;
  116. }
  117. }
  118. if (a->dcount) {
  119. if (!smbbufferreadskipto(b, a->doffset)) {
  120. smbstringprint(errmsgp, "smbtransactiondecoderesponse: invalid data offset");
  121. return 0;
  122. }
  123. if (!smbbuffercopy(t->out.data, b, a->dcount)) {
  124. smbstringprint(errmsgp, "smbtransactiondecoderesponse: not enough data for data");
  125. return 0;
  126. }
  127. }
  128. return 1;
  129. }
  130. int
  131. smbtransactiondecoderesponse(SmbTransaction *t, SmbHeader *h, uchar *pdata, SmbBuffer *b, char **errmsgp)
  132. {
  133. Args a;
  134. if (h->command != SMB_COM_TRANSACTION) {
  135. smbstringprint(errmsgp, "smbtransactiondecoderesponse: not an SMB_COM_TRANSACTION");
  136. return 0;
  137. }
  138. if (h->wordcount < 10) {
  139. smbstringprint(errmsgp, "smbtransactiondecoderesponse: word count less than 10");
  140. return -1;
  141. }
  142. t->out.tpcount = smbnhgets(pdata); pdata += 2;
  143. t->out.tdcount = smbnhgets(pdata); pdata += 2;
  144. pdata += 2;
  145. a.pcount = smbnhgets(pdata); pdata += 2;
  146. a.poffset = smbnhgets(pdata); pdata += 2;
  147. a.pdisplacement = smbnhgets(pdata); pdata += 2;
  148. a.dcount = smbnhgets(pdata); pdata += 2;
  149. a.doffset = smbnhgets(pdata); pdata += 2;
  150. a.ddisplacement = smbnhgets(pdata); pdata += 2;
  151. a.scount = *pdata;
  152. if (a.scount != h->wordcount - 10) {
  153. smbstringprint(errmsgp, "smbtransactiondecoderesponse: scount inconsistent");
  154. return 0;
  155. }
  156. return decoderesponse(t, &a, b, errmsgp);
  157. }
  158. int
  159. smbtransactiondecoderesponse2(SmbTransaction *t, SmbHeader *h, uchar *pdata, SmbBuffer *b, char **errmsgp)
  160. {
  161. Args a;
  162. if (h->command != SMB_COM_TRANSACTION2) {
  163. smbstringprint(errmsgp, "smbtransactiondecoderesponse2: not an SMB_COM_TRANSACTION2");
  164. return 0;
  165. }
  166. if (h->wordcount < 10) {
  167. smbstringprint(errmsgp, "smbtransactiondecoderesponse2: word count less than 10");
  168. return -1;
  169. }
  170. t->out.tpcount = smbnhgets(pdata); pdata += 2;
  171. t->out.tdcount = smbnhgets(pdata); pdata += 2;
  172. pdata += 2;
  173. a.pcount = smbnhgets(pdata); pdata += 2;
  174. a.poffset = smbnhgets(pdata); pdata += 2;
  175. a.pdisplacement = smbnhgets(pdata); pdata += 2;
  176. a.dcount = smbnhgets(pdata); pdata += 2;
  177. a.doffset = smbnhgets(pdata); pdata += 2;
  178. a.ddisplacement = smbnhgets(pdata); pdata += 2;
  179. a.scount = *pdata;
  180. if (a.scount != h->wordcount - 10) {
  181. smbstringprint(errmsgp, "smbtransactiondecoderesponse2: scount inconsistent");
  182. return 0;
  183. }
  184. return decoderesponse(t, &a, b, errmsgp);
  185. }
  186. int
  187. smbtransactiondecodeprimary(SmbTransaction *t, SmbHeader *h, uchar *pdata, SmbBuffer *b, char **errmsgp)
  188. {
  189. return _smbtransactiondecodeprimary(t, h, pdata, b, 1, errmsgp);
  190. }
  191. int
  192. smbtransactiondecodeprimary2(SmbTransaction *t, SmbHeader *h, uchar *pdata, SmbBuffer *b, char **errmsgp)
  193. {
  194. return _smbtransactiondecodeprimary(t, h, pdata, b, 0, errmsgp);
  195. }
  196. void
  197. smbtransactionfree(SmbTransaction *t)
  198. {
  199. free(t->in.parameters);
  200. free(t->in.data);
  201. free(t->in.setup);
  202. free(t->in.name);
  203. smbbufferfree(&t->out.parameters);
  204. smbbufferfree(&t->out.data);
  205. }
  206. static int
  207. _transactionencodeprimary(SmbTransaction *t, uchar cmd, SmbHeader *h, SmbPeerInfo *p, SmbBuffer *ob,
  208. uchar *wordcountp, ushort *bytecountp, char **errmsgp)
  209. {
  210. SmbHeader mh;
  211. ulong countsfixupoffset, bytecountfixupoffset;
  212. int x;
  213. mh = *h;
  214. *wordcountp = mh.wordcount = 14 + t->in.scount;
  215. mh.flags &= ~SMB_FLAGS_SERVER_TO_REDIR;
  216. mh.command = cmd;
  217. if (!smbbufferputheader(ob, &mh, p)) {
  218. toosmall:
  219. smbstringprint(errmsgp, "output buffer too small");
  220. return 0;
  221. }
  222. if (t->in.tpcount > 65535 || t->in.tdcount > 65535 || t->in.maxpcount > 65535 || t->in.maxdcount > 65535) {
  223. smbstringprint(errmsgp, "counts too big");
  224. return 0;
  225. }
  226. if (!smbbufferputs(ob, t->in.tpcount)
  227. || !smbbufferputs(ob, t->in.tdcount)
  228. || !smbbufferputs(ob, t->in.maxpcount)
  229. || !smbbufferputs(ob, t->in.maxdcount)
  230. || !smbbufferputb(ob, t->in.maxscount)
  231. || !smbbufferputb(ob, 0)
  232. || !smbbufferputs(ob, t->in.flags)
  233. || !smbbufferputl(ob, 0)
  234. || !smbbufferputs(ob, 0))
  235. goto toosmall;
  236. countsfixupoffset = smbbufferwriteoffset(ob);
  237. if (!smbbufferputs(ob, 0)
  238. || !smbbufferputs(ob, 0)
  239. || !smbbufferputs(ob, 0)
  240. || !smbbufferputs(ob, 0))
  241. goto toosmall;
  242. if (!smbbufferputb(ob, t->in.scount)
  243. || !smbbufferputb(ob, 0))
  244. goto toosmall;
  245. for (x = 0; x < t->in.scount; x++)
  246. if (!smbbufferputs(ob, t->in.setup[x]))
  247. goto toosmall;
  248. bytecountfixupoffset = smbbufferwriteoffset(ob);
  249. if (!smbbufferputs(ob, 0))
  250. goto toosmall;
  251. smbbufferwritelimit(ob, smbbufferwriteoffset(ob) + 65535);
  252. if (!smbbufferputstring(ob, p, SMB_STRING_UPCASE, t->in.name))
  253. goto toosmall;
  254. if (t->in.pcount < t->in.tpcount) {
  255. ulong align = smbbufferwriteoffset(ob) & 1;
  256. ulong pthistime;
  257. pthistime = smbbufferwritespace(ob) - align;
  258. if (pthistime > t->in.tpcount - t->in.pcount)
  259. pthistime = t->in.tpcount - t->in.pcount;
  260. if (pthistime > 65535)
  261. pthistime = 65535;
  262. if (smbbufferwriteoffset(ob) > 65535)
  263. pthistime = 0;
  264. if (pthistime) {
  265. assert(smbbufferalignl2(ob, 0));
  266. assert(smbbufferoffsetputs(ob, countsfixupoffset, pthistime));
  267. assert(smbbufferoffsetputs(ob, countsfixupoffset + 2, smbbufferwriteoffset(ob)));
  268. assert(smbbufferputbytes(ob, t->in.parameters + t->in.pcount, pthistime));
  269. }
  270. t->in.pcount += pthistime;
  271. }
  272. if (t->in.dcount < t->in.tdcount) {
  273. ulong align = smbbufferwriteoffset(ob) & 1;
  274. ulong dthistime;
  275. dthistime = smbbufferwritespace(ob) - align;
  276. if (dthistime > t->in.tdcount - t->in.dcount)
  277. dthistime = t->in.tdcount - t->in.dcount;
  278. if (dthistime > 65535)
  279. dthistime = 65535;
  280. if (smbbufferwriteoffset(ob) > 65535)
  281. dthistime = 0;
  282. if (dthistime) {
  283. assert(smbbufferalignl2(ob, 0));
  284. assert(smbbufferoffsetputs(ob, countsfixupoffset + 4, dthistime));
  285. assert(smbbufferoffsetputs(ob, countsfixupoffset + 6, smbbufferwriteoffset(ob)));
  286. assert(smbbufferputbytes(ob, t->in.data + t->in.dcount, dthistime));
  287. }
  288. t->in.dcount += dthistime;
  289. }
  290. *bytecountp = smbbufferwriteoffset(ob) - bytecountfixupoffset - 2;
  291. assert(smbbufferoffsetputs(ob, bytecountfixupoffset, *bytecountp));
  292. return 1;
  293. }
  294. int
  295. smbtransactionencodeprimary(SmbTransaction *t, SmbHeader *h, SmbPeerInfo *p, SmbBuffer *ob,
  296. uchar *wordcountp, ushort *bytecountp, char **errmsgp)
  297. {
  298. return _transactionencodeprimary(t, SMB_COM_TRANSACTION, h, p,ob, wordcountp, bytecountp, errmsgp);
  299. };
  300. int
  301. smbtransactionencodeprimary2(SmbTransaction *t, SmbHeader *h, SmbPeerInfo *p, SmbBuffer *ob,
  302. uchar *wordcountp, ushort *bytecountp, char **errmsgp)
  303. {
  304. return _transactionencodeprimary(t, SMB_COM_TRANSACTION2, h, p,ob, wordcountp, bytecountp, errmsgp);
  305. };
  306. int
  307. _transactionencoderesponse(SmbTransaction *t, SmbHeader *h, SmbPeerInfo *p, SmbBuffer *ob, uchar cmd,
  308. char **errmsgp)
  309. {
  310. SmbHeader mh;
  311. ulong countsfixupoffset, bytecountfixupoffset;
  312. int palign, dalign;
  313. ulong pbytecount, dbytecount;
  314. ulong poffset, doffset;
  315. if (t->in.maxpcount > 65535 || t->in.maxdcount > 65535) {
  316. smbstringprint(errmsgp, "counts too big");
  317. return 0;
  318. }
  319. mh = *h;
  320. mh.wordcount = 10;
  321. mh.flags &= ~SMB_FLAGS_SERVER_TO_REDIR;
  322. mh.command = cmd;
  323. mh.errclass = SUCCESS;
  324. mh.error = SUCCESS;
  325. if (!smbbufferputheader(ob, &mh, p)
  326. || !smbbufferputs(ob, smbbufferwriteoffset(t->out.parameters))
  327. || !smbbufferputs(ob, smbbufferwriteoffset(t->out.data))
  328. || !smbbufferputs(ob, 0)) {
  329. toosmall:
  330. smbstringprint(errmsgp, "output buffer too small");
  331. goto toosmall;
  332. }
  333. countsfixupoffset = smbbufferwriteoffset(ob);
  334. if (!smbbufferputbytes(ob, nil, 6 * sizeof(ushort))
  335. || !smbbufferputb(ob, 0) // scount == 0
  336. || !smbbufferputb(ob, 0)) // reserved2
  337. goto toosmall;
  338. /* now the byte count */
  339. bytecountfixupoffset = smbbufferwriteoffset(ob);
  340. if (!smbbufferputs(ob, 0))
  341. goto toosmall;
  342. smbbufferwritelimit(ob, smbbufferwriteoffset(ob) + 65535);
  343. palign = bytecountfixupoffset & 1;
  344. if (palign && !smbbufferputb(ob, 0))
  345. goto toosmall;
  346. pbytecount = smbbufferreadspace(t->out.parameters);
  347. if (pbytecount > smbbufferwritespace(ob))
  348. pbytecount = smbbufferwritespace(ob);
  349. poffset = smbbufferwriteoffset(ob);
  350. if (poffset > 65535)
  351. goto toosmall;
  352. if (!smbbufferputbytes(ob, smbbufferreadpointer(t->out.parameters), pbytecount))
  353. goto toosmall;
  354. dalign = smbbufferwritespace(ob) > 0 && (smbbufferwriteoffset(ob) & 1) != 0;
  355. if (dalign && !smbbufferputb(ob, 0))
  356. goto toosmall;
  357. dbytecount = smbbufferreadspace(t->out.data);
  358. if (dbytecount > smbbufferwritespace(ob))
  359. dbytecount = smbbufferwritespace(ob);
  360. doffset = smbbufferwriteoffset(ob);
  361. if (doffset > 65535)
  362. goto toosmall;
  363. if (!smbbufferputbytes(ob, smbbufferreadpointer(t->out.data), dbytecount))
  364. goto toosmall;
  365. if (!smbbufferoffsetputs(ob, bytecountfixupoffset, palign + pbytecount + dalign + dbytecount)
  366. || !smbbufferoffsetputs(ob, countsfixupoffset, pbytecount)
  367. || !smbbufferoffsetputs(ob, countsfixupoffset + 2, poffset)
  368. || !smbbufferoffsetputs(ob, countsfixupoffset + 4, smbbufferreadoffset(t->out.parameters))
  369. || !smbbufferoffsetputs(ob, countsfixupoffset + 6, dbytecount)
  370. || !smbbufferoffsetputs(ob, countsfixupoffset + 8, doffset)
  371. || !smbbufferoffsetputs(ob, countsfixupoffset + 10, smbbufferreadoffset(t->out.data)))
  372. goto toosmall;
  373. assert(smbbufferoffsetputs(ob, bytecountfixupoffset, smbbufferwriteoffset(ob) - bytecountfixupoffset - 2));
  374. smbbuffergetbytes(t->out.parameters, nil, pbytecount);
  375. smbbuffergetbytes(t->out.data, nil, dbytecount);
  376. return 1;
  377. }
  378. int
  379. smbtransactionencoderesponse(SmbTransaction *t, SmbHeader *h, SmbPeerInfo *p, SmbBuffer *ob, char **errmsgp)
  380. {
  381. return _transactionencoderesponse(t, h, p, ob, SMB_COM_TRANSACTION, errmsgp);
  382. }
  383. int
  384. smbtransactionencoderesponse2(SmbTransaction *t, SmbHeader *h, SmbPeerInfo *p, SmbBuffer *ob, char **errmsgp)
  385. {
  386. return _transactionencoderesponse(t, h, p, ob, SMB_COM_TRANSACTION2, errmsgp);
  387. }
  388. int
  389. smbtransactionrespond(SmbTransaction *t, SmbHeader *h, SmbPeerInfo *p, SmbBuffer *ob, SmbTransactionMethod *method, void *magic, char **errmsgp)
  390. {
  391. /* generate one or more responses */
  392. while (smbbufferreadspace(t->out.parameters) || smbbufferreadspace(t->out.data)) {
  393. assert(method->encoderesponse);
  394. if (!(*method->encoderesponse)(t, h, p, ob, errmsgp))
  395. return 0;
  396. assert(method->sendresponse);
  397. if (!(*method->sendresponse)(magic, ob, errmsgp))
  398. return 0;
  399. }
  400. return 1;
  401. }
  402. int
  403. smbtransactionnbdgramsend(void *magic, SmbBuffer *ob, char **errmsgp)
  404. {
  405. NbDgramSendParameters *p = magic;
  406. //print("sending to %B\n", p->to);
  407. //nbdumpdata(smbbufferreadpointer(ob), smbbufferreadspace(ob));
  408. if (!nbdgramsend(p, smbbufferreadpointer(ob), smbbufferreadspace(ob))) {
  409. smbstringprint(errmsgp, "dgram send failed");
  410. return 0;
  411. }
  412. return 1;
  413. }
  414. SmbTransactionMethod smbtransactionmethoddgram = {
  415. .encodeprimary = smbtransactionencodeprimary,
  416. .sendrequest = smbtransactionnbdgramsend,
  417. .encoderesponse = smbtransactionencoderesponse,
  418. };
  419. int
  420. smbtransactionexecute(SmbTransaction *t, SmbHeader *h, SmbPeerInfo *p, SmbBuffer *iob, SmbTransactionMethod *method, void *magic, SmbHeader *rhp, char **errmsgp)
  421. {
  422. uchar sentwordcount;
  423. ushort sentbytecount;
  424. SmbHeader rh;
  425. smbbufferreset(iob);
  426. if (!(*method->encodeprimary)(t, h, p, iob, &sentwordcount, &sentbytecount, errmsgp))
  427. return 0;
  428. // smblogprint(-1, "sent...\n");
  429. // smblogdata(-1, smblogprint, smbbufferreadpointer(iob), smbbufferreadspace(iob));
  430. if (!(*method->sendrequest)(magic, iob, errmsgp))
  431. return 0;
  432. if (t->in.pcount < t->in.tpcount || t->in.dcount < t->in.tdcount) {
  433. uchar wordcount;
  434. ushort bytecount;
  435. /* secondary needed */
  436. if (method->encodesecondary == nil || method->receiveintermediate == nil) {
  437. smbstringprint(errmsgp, "buffer too small and secondaries not allowed");
  438. return 0;
  439. }
  440. if (!(*method->receiveintermediate)(magic, &wordcount, &bytecount, errmsgp))
  441. return 0;
  442. if (sentwordcount != wordcount || sentbytecount != bytecount) {
  443. smbstringprint(errmsgp, "server intermediate reply counts differ");
  444. return 0;
  445. }
  446. do {
  447. if (!(*method->encodesecondary)(t, h, iob, errmsgp))
  448. return 0;
  449. if (!(*method->sendrequest)(magic, iob, errmsgp))
  450. return 0;
  451. } while (t->in.pcount < t->in.tpcount || t->in.dcount < t->in.tdcount);
  452. }
  453. if (method->receiveresponse == nil || method->decoderesponse == nil)
  454. return 1;
  455. do {
  456. uchar *pdata;
  457. ushort bytecount;
  458. if (!(*method->receiveresponse)(magic, iob, errmsgp))
  459. return 0;
  460. if (!smbbuffergetheader(iob, &rh, &pdata, &bytecount)) {
  461. smbstringprint(errmsgp, "smbtransactionexecute: invalid response header");
  462. return 0;
  463. }
  464. if (!smbcheckheaderdirection(&rh, 1, errmsgp))
  465. return 0;
  466. if (rh.errclass != SUCCESS) {
  467. smbstringprint(errmsgp, "smbtransactionexecute: remote error %d/%d", rh.errclass, rh.error);
  468. return 0;
  469. }
  470. if (!smbbuffertrimreadlen(iob, bytecount)) {
  471. smbstringprint(errmsgp, "smbtransactionexecute: invalid bytecount");
  472. return 0;
  473. }
  474. // smblogprint(-1, "received...\n");
  475. // smblogdata(-1, smblogprint, smbbufferreadpointer(iob), smbbufferreadspace(iob));
  476. if (!(*method->decoderesponse)(t, &rh, pdata, iob, errmsgp))
  477. return 0;
  478. } while (smbbufferwriteoffset(t->out.parameters) < t->out.tpcount || smbbufferwriteoffset(t->out.data) < t->out.tdcount);
  479. if (rhp)
  480. *rhp = rh;
  481. return 1;
  482. }